@malloy-publisher/server 0.0.80 → 0.0.82

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/mcp/server.ts CHANGED
@@ -1,16 +1,17 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { ProjectStore } from "../service/project_store";
3
3
 
4
- import { registerProjectResource } from "./resources/project_resource";
5
- import { registerPackageResource } from "./resources/package_resource";
4
+ import { logger } from "../logger";
5
+ import { registerPromptCapability } from "./prompts/prompt_service.js";
6
6
  import { registerModelResource } from "./resources/model_resource";
7
- import { registerSourceResource } from "./resources/source_resource";
7
+ import { registerNotebookResource } from "./resources/notebook_resource";
8
+ import { registerPackageResource } from "./resources/package_resource";
9
+ import { registerProjectResource } from "./resources/project_resource";
8
10
  import { registerQueryResource } from "./resources/query_resource";
11
+ import { registerSourceResource } from "./resources/source_resource";
9
12
  import { registerViewResource } from "./resources/view_resource";
10
- import { registerNotebookResource } from "./resources/notebook_resource";
11
- import { registerExecuteQueryTool } from "./tools/execute_query_tool";
12
13
  import { registerTools } from "./tools/discovery_tools";
13
- import { registerPromptCapability } from "./prompts/prompt_service.js";
14
+ import { registerExecuteQueryTool } from "./tools/execute_query_tool";
14
15
 
15
16
  export const testServerInfo = {
16
17
  name: "malloy-publisher-mcp-server",
@@ -20,42 +21,42 @@ export const testServerInfo = {
20
21
  };
21
22
 
22
23
  export function initializeMcpServer(projectStore: ProjectStore): McpServer {
23
- console.log("[MCP Init] Starting initializeMcpServer...");
24
- const startTime = Date.now();
24
+ logger.info("[MCP Init] Starting initializeMcpServer...");
25
+ const startTime = performance.now();
25
26
 
26
27
  const mcpServer = new McpServer(testServerInfo);
27
28
 
28
- console.log("[MCP Init] Registering project resource...");
29
+ logger.info("[MCP Init] Registering project resource...");
29
30
  registerProjectResource(mcpServer, projectStore);
30
- console.log("[MCP Init] Registering package resource...");
31
+ logger.info("[MCP Init] Registering package resource...");
31
32
  registerPackageResource(mcpServer, projectStore);
32
33
 
33
34
  // Register more specific templates first
34
- console.log("[MCP Init] Registering notebook resource...");
35
+ logger.info("[MCP Init] Registering notebook resource...");
35
36
  registerNotebookResource(mcpServer, projectStore);
36
- console.log("[MCP Init] Registering source resource...");
37
+ logger.info("[MCP Init] Registering source resource...");
37
38
  registerSourceResource(mcpServer, projectStore);
38
- console.log("[MCP Init] Registering query resource...");
39
+ logger.info("[MCP Init] Registering query resource...");
39
40
  registerQueryResource(mcpServer, projectStore);
40
- console.log("[MCP Init] Registering view resource...");
41
+ logger.info("[MCP Init] Registering view resource...");
41
42
  registerViewResource(mcpServer, projectStore);
42
43
 
43
44
  // Register the general model template last among resource types
44
- console.log("[MCP Init] Registering model resource...");
45
+ logger.info("[MCP Init] Registering model resource...");
45
46
  registerModelResource(mcpServer, projectStore);
46
47
 
47
- console.log("[MCP Init] Registering executeQuery tool...");
48
+ logger.info("[MCP Init] Registering executeQuery tool...");
48
49
  registerExecuteQueryTool(mcpServer, projectStore);
49
50
 
50
51
  registerTools(mcpServer, projectStore);
51
52
 
52
- console.log("[MCP Init] Registering prompt capability...");
53
+ logger.info("[MCP Init] Registering prompt capability...");
53
54
  registerPromptCapability(mcpServer, projectStore);
54
55
 
55
- const endTime = Date.now();
56
- console.log(
57
- `[MCP Init] Finished initializeMcpServer. Duration: ${endTime - startTime}ms`,
58
- );
56
+ const endTime = performance.now();
57
+ logger.info(`[MCP Init] Finished initializeMcpServer`, {
58
+ duration: endTime - startTime,
59
+ });
59
60
 
60
61
  return mcpServer;
61
62
  }
@@ -1,11 +1,11 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
2
+ import { ErrorCode, McpError } from "@modelcontextprotocol/sdk/types.js";
3
3
  import { z } from "zod";
4
+ import { logger } from "../../logger";
4
5
  import { ProjectStore } from "../../service/project_store";
5
- import { getModelForQuery } from "../handler_utils";
6
6
  import { getMalloyErrorDetails, type ErrorDetails } from "../error_messages";
7
+ import { buildMalloyUri, getModelForQuery } from "../handler_utils";
7
8
  import { MCP_ERROR_MESSAGES } from "../mcp_constants";
8
- import { buildMalloyUri } from "../handler_utils";
9
9
 
10
10
  // Zod shape defining required/optional params for executeQuery
11
11
  const executeQueryShape = {
@@ -51,10 +51,7 @@ export function registerExecuteQueryTool(
51
51
  queryName,
52
52
  } = params;
53
53
 
54
- console.log(
55
- "[MCP Tool executeQuery] Received params:",
56
- JSON.stringify(params),
57
- );
54
+ logger.info("[MCP Tool executeQuery] Received params:", { params });
58
55
 
59
56
  const hasAdhocQuery = !!query;
60
57
  const hasNamedQuery = !!queryName;
@@ -74,7 +71,7 @@ export function registerExecuteQueryTool(
74
71
  // Zod/SDK handles missing required fields (packageName, modelPath) based on the shape
75
72
 
76
73
  // --- Get Package and Model ---
77
- console.log(
74
+ logger.info(
78
75
  `[MCP Tool executeQuery] Calling getModelForQuery for ${projectName}/${packageName}/${modelPath}`,
79
76
  );
80
77
  const modelResult = await getModelForQuery(
@@ -113,7 +110,7 @@ export function registerExecuteQueryTool(
113
110
 
114
111
  // --- Execute Query ---
115
112
  const { model } = modelResult;
116
- console.log(
113
+ logger.info(
117
114
  `[MCP Tool executeQuery] Model found. Proceeding to execute query.`,
118
115
  );
119
116
  try {
@@ -192,9 +189,9 @@ export function registerExecuteQueryTool(
192
189
  );
193
190
  } catch (queryError) {
194
191
  // Handle query execution errors (syntax errors, invalid queries, etc.)
195
- console.error(
192
+ logger.error(
196
193
  `[MCP Server Error] Error executing query in ${projectName}/${packageName}/${modelPath}:`,
197
- queryError,
194
+ { error: queryError },
198
195
  );
199
196
  const errorDetails: ErrorDetails = getMalloyErrorDetails(
200
197
  "executeQuery",
package/src/server.ts CHANGED
@@ -4,7 +4,6 @@ import cors from "cors";
4
4
  import express from "express";
5
5
  import * as http from "http";
6
6
  import { createProxyMiddleware } from "http-proxy-middleware";
7
- import morgan from "morgan";
8
7
  import { AddressInfo } from "net";
9
8
  import * as path from "path";
10
9
  import { ConnectionController } from "./controller/connection.controller";
@@ -14,6 +13,7 @@ import { PackageController } from "./controller/package.controller";
14
13
  import { QueryController } from "./controller/query.controller";
15
14
  import { ScheduleController } from "./controller/schedule.controller";
16
15
  import { internalErrorToHttpError, NotImplementedError } from "./errors";
16
+ import { logger, loggerMiddleware } from "./logger";
17
17
  import { initializeMcpServer } from "./mcp/server";
18
18
  import { ProjectStore } from "./service/project_store";
19
19
 
@@ -79,7 +79,7 @@ const API_PREFIX = "/api/v0";
79
79
  const isDevelopment = process.env["NODE_ENV"] === "development";
80
80
 
81
81
  const app = express();
82
- app.use(morgan("tiny"));
82
+ app.use(loggerMiddleware);
83
83
  app.use(cors());
84
84
 
85
85
  const projectStore = new ProjectStore(SERVER_ROOT);
@@ -96,7 +96,7 @@ mcpApp.use(MCP_ENDPOINT, express.json());
96
96
  mcpApp.use(MCP_ENDPOINT, cors());
97
97
 
98
98
  mcpApp.all(MCP_ENDPOINT, async (req, res) => {
99
- console.log(`[MCP Debug] Handling ${req.method} (Stateless)`);
99
+ logger.info(`[MCP Debug] Handling ${req.method} (Stateless)`);
100
100
 
101
101
  try {
102
102
  if (req.method === "POST") {
@@ -105,35 +105,34 @@ mcpApp.all(MCP_ENDPOINT, async (req, res) => {
105
105
  });
106
106
 
107
107
  transport.onclose = () => {
108
- console.log(
108
+ logger.info(
109
109
  `[MCP Transport Info] Stateless transport closed for a request.`,
110
110
  );
111
111
  };
112
112
  transport.onerror = (err: Error) => {
113
- console.error(
114
- `[MCP Transport Error] Stateless transport error:`,
115
- err,
116
- );
113
+ logger.error(`[MCP Transport Error] Stateless transport error:`, {
114
+ error: err,
115
+ });
117
116
  };
118
117
 
119
118
  const requestMcpServer = initializeMcpServer(projectStore);
120
119
  await requestMcpServer.connect(transport);
121
120
 
122
121
  res.on("close", () => {
123
- console.log(
122
+ logger.info(
124
123
  "[MCP Transport Info] Response closed, cleaning up stateless transport.",
125
124
  );
126
125
  transport.close().catch((err) => {
127
- console.error(
126
+ logger.error(
128
127
  "[MCP Transport Error] Error closing stateless transport on response close:",
129
- err,
128
+ { error: err },
130
129
  );
131
130
  });
132
131
  });
133
132
 
134
133
  await transport.handleRequest(req, res, req.body);
135
134
  } else if (req.method === "GET" || req.method === "DELETE") {
136
- console.warn(
135
+ logger.warn(
137
136
  `[MCP Transport Warn] Method Not Allowed in Stateless Mode: ${req.method}`,
138
137
  );
139
138
  res.setHeader("Allow", "POST");
@@ -147,7 +146,7 @@ mcpApp.all(MCP_ENDPOINT, async (req, res) => {
147
146
  });
148
147
  return;
149
148
  } else {
150
- console.warn(`[MCP Transport Warn] Method Not Allowed: ${req.method}`);
149
+ logger.warn(`[MCP Transport Warn] Method Not Allowed: ${req.method}`);
151
150
  res.setHeader("Allow", "POST");
152
151
  res.status(405).json({
153
152
  jsonrpc: "2.0",
@@ -157,9 +156,9 @@ mcpApp.all(MCP_ENDPOINT, async (req, res) => {
157
156
  return;
158
157
  }
159
158
  } catch (error) {
160
- console.error(
159
+ logger.error(
161
160
  `[MCP Transport Error] Unhandled error in ${req.method} handler (Stateless):`,
162
- error,
161
+ { error },
163
162
  );
164
163
  if (!res.headersSent) {
165
164
  res.status(500).json({
@@ -184,10 +183,7 @@ if (!isDevelopment) {
184
183
  } else {
185
184
  // In development mode, proxy requests to React dev server
186
185
  // Handle API routes first
187
- app.use(`${API_PREFIX}`, (req, res, next) => {
188
- console.log(`[Express] Handling API request: ${req.method} ${req.url}`);
189
- next();
190
- });
186
+ app.use(`${API_PREFIX}`, loggerMiddleware);
191
187
 
192
188
  // Proxy everything else to Vite
193
189
  app.use(
@@ -214,7 +210,7 @@ app.get(`${API_PREFIX}/projects`, async (_req, res) => {
214
210
  try {
215
211
  res.status(200).json(await projectStore.listProjects());
216
212
  } catch (error) {
217
- console.error(error);
213
+ logger.error(error);
218
214
  const { json, status } = internalErrorToHttpError(error as Error);
219
215
  res.status(status).json(json);
220
216
  }
@@ -228,7 +224,7 @@ app.get(`${API_PREFIX}/projects/:projectName`, async (req, res) => {
228
224
  );
229
225
  res.status(200).json(await project.getProjectMetadata());
230
226
  } catch (error) {
231
- console.error(error);
227
+ logger.error(error);
232
228
  const { json, status } = internalErrorToHttpError(error as Error);
233
229
  res.status(status).json(json);
234
230
  }
@@ -240,7 +236,7 @@ app.get(`${API_PREFIX}/projects/:projectName/connections`, async (req, res) => {
240
236
  await connectionController.listConnections(req.params.projectName),
241
237
  );
242
238
  } catch (error) {
243
- console.error(error);
239
+ logger.error(error);
244
240
  const { json, status } = internalErrorToHttpError(error as Error);
245
241
  res.status(status).json(json);
246
242
  }
@@ -257,7 +253,7 @@ app.get(
257
253
  ),
258
254
  );
259
255
  } catch (error) {
260
- console.error(error);
256
+ logger.error(error);
261
257
  const { json, status } = internalErrorToHttpError(error as Error);
262
258
  res.status(status).json(json);
263
259
  }
@@ -275,7 +271,7 @@ app.get(
275
271
  ),
276
272
  );
277
273
  } catch (error) {
278
- console.error(error);
274
+ logger.error(error);
279
275
  const { json, status } = internalErrorToHttpError(error as Error);
280
276
  res.status(status).json(json);
281
277
  }
@@ -293,7 +289,7 @@ app.get(
293
289
  ),
294
290
  );
295
291
  } catch (error) {
296
- console.error(error);
292
+ logger.error(error);
297
293
  const { json, status } = internalErrorToHttpError(error as Error);
298
294
  res.status(status).json(json);
299
295
  }
@@ -303,17 +299,17 @@ app.get(
303
299
  app.get(
304
300
  `${API_PREFIX}/projects/:projectName/connections/:connectionName/schemas/:schemaName/tables`,
305
301
  async (req, res) => {
306
- console.log("req.params", req.params);
302
+ logger.info("req.params", { params: req.params });
307
303
  try {
308
304
  const results = await connectionController.listTables(
309
305
  req.params.projectName,
310
306
  req.params.connectionName,
311
307
  req.params.schemaName,
312
308
  );
313
- console.log("results", results);
309
+ logger.info("results", { results });
314
310
  res.status(200).json(results);
315
311
  } catch (error) {
316
- console.error(error);
312
+ logger.error(error);
317
313
  const { json, status } = internalErrorToHttpError(error as Error);
318
314
  res.status(status).json(json);
319
315
  }
@@ -332,7 +328,7 @@ app.get(
332
328
  ),
333
329
  );
334
330
  } catch (error) {
335
- console.error(error);
331
+ logger.error(error);
336
332
  const { json, status } = internalErrorToHttpError(error as Error);
337
333
  res.status(status).json(json);
338
334
  }
@@ -352,7 +348,7 @@ app.get(
352
348
  ),
353
349
  );
354
350
  } catch (error) {
355
- console.error(error);
351
+ logger.error(error);
356
352
  const { json, status } = internalErrorToHttpError(error as Error);
357
353
  res.status(status).json(json);
358
354
  }
@@ -372,7 +368,7 @@ app.get(
372
368
  ),
373
369
  );
374
370
  } catch (error) {
375
- console.error(error);
371
+ logger.error(error);
376
372
  const { json, status } = internalErrorToHttpError(error as Error);
377
373
  res.status(status).json(json);
378
374
  }
@@ -391,7 +387,7 @@ app.get(
391
387
  ),
392
388
  );
393
389
  } catch (error) {
394
- console.error(error);
390
+ logger.error(error);
395
391
  const { json, status } = internalErrorToHttpError(error as Error);
396
392
  res.status(status).json(json);
397
393
  }
@@ -409,7 +405,7 @@ app.get(`${API_PREFIX}/projects/:projectName/packages`, async (req, res) => {
409
405
  await packageController.listPackages(req.params.projectName),
410
406
  );
411
407
  } catch (error) {
412
- console.error(error);
408
+ logger.error(error);
413
409
  const { json, status } = internalErrorToHttpError(error as Error);
414
410
  res.status(status).json(json);
415
411
  }
@@ -432,7 +428,7 @@ app.get(
432
428
  ),
433
429
  );
434
430
  } catch (error) {
435
- console.error(error);
431
+ logger.error(error);
436
432
  const { json, status } = internalErrorToHttpError(error as Error);
437
433
  res.status(status).json(json);
438
434
  }
@@ -455,7 +451,7 @@ app.get(
455
451
  ),
456
452
  );
457
453
  } catch (error) {
458
- console.error(error);
454
+ logger.error(error);
459
455
  const { json, status } = internalErrorToHttpError(error as Error);
460
456
  res.status(status).json(json);
461
457
  }
@@ -480,7 +476,7 @@ app.get(
480
476
  ),
481
477
  );
482
478
  } catch (error) {
483
- console.error(error);
479
+ logger.error(error);
484
480
  const { json, status } = internalErrorToHttpError(error as Error);
485
481
  res.status(status).json(json);
486
482
  }
@@ -503,7 +499,7 @@ app.get(
503
499
  ),
504
500
  );
505
501
  } catch (error) {
506
- console.error(error);
502
+ logger.error(error);
507
503
  const { json, status } = internalErrorToHttpError(error as Error);
508
504
  res.status(status).json(json);
509
505
  }
@@ -528,7 +524,7 @@ app.get(
528
524
  ),
529
525
  );
530
526
  } catch (error) {
531
- console.error(error);
527
+ logger.error(error);
532
528
  const { json, status } = internalErrorToHttpError(error as Error);
533
529
  res.status(status).json(json);
534
530
  }
@@ -556,7 +552,7 @@ app.get(
556
552
  ),
557
553
  );
558
554
  } catch (error) {
559
- console.error(error);
555
+ logger.error(error);
560
556
  const { json, status } = internalErrorToHttpError(error as Error);
561
557
  res.status(status).json(json);
562
558
  }
@@ -579,7 +575,7 @@ app.get(
579
575
  ),
580
576
  );
581
577
  } catch (error) {
582
- console.error(error);
578
+ logger.error(error);
583
579
  const { json, status } = internalErrorToHttpError(error as Error);
584
580
  res.status(status).json(json);
585
581
  }
@@ -602,7 +598,7 @@ app.get(
602
598
  ),
603
599
  );
604
600
  } catch (error) {
605
- console.error(error);
601
+ logger.error(error);
606
602
  const { json, status } = internalErrorToHttpError(error as Error);
607
603
  res.status(status).json(json);
608
604
  }
@@ -615,7 +611,7 @@ if (!isDevelopment) {
615
611
  }
616
612
 
617
613
  app.use((err: Error, _req: express.Request, res: express.Response) => {
618
- console.error("Unhandled error:", err);
614
+ logger.error("Unhandled error:", err);
619
615
  const { json, status } = internalErrorToHttpError(err);
620
616
  res.status(status).json(json);
621
617
  });
@@ -623,18 +619,18 @@ app.use((err: Error, _req: express.Request, res: express.Response) => {
623
619
  const mainServer = http.createServer(app);
624
620
  mainServer.listen(PUBLISHER_PORT, PUBLISHER_HOST, () => {
625
621
  const address = mainServer.address() as AddressInfo;
626
- console.log(
622
+ logger.info(
627
623
  `Publisher server listening at http://${address.address}:${address.port}`,
628
624
  );
629
625
  if (isDevelopment) {
630
- console.log(
626
+ logger.info(
631
627
  "Running in development mode - proxying to React dev server at http://localhost:5173",
632
628
  );
633
629
  }
634
630
  });
635
631
 
636
632
  const mcpHttpServer = mcpApp.listen(MCP_PORT, PUBLISHER_HOST, () => {
637
- console.log(`MCP server listening at http://${PUBLISHER_HOST}:${MCP_PORT}`);
633
+ logger.info(`MCP server listening at http://${PUBLISHER_HOST}:${MCP_PORT}`);
638
634
  });
639
635
 
640
636
  export { app, mainServer as httpServer, mcpApp, mcpHttpServer };
@@ -1,17 +1,18 @@
1
+ import { BigQuery } from "@google-cloud/bigquery";
1
2
  import fs from "fs";
2
- import path from "path";
3
3
  import os from "os";
4
- import { v4 as uuidv4 } from "uuid";
4
+ import path from "path";
5
5
  import { Pool } from "pg";
6
- import { BigQuery } from "@google-cloud/bigquery";
7
6
  import * as snowflake from "snowflake-sdk";
7
+ import { v4 as uuidv4 } from "uuid";
8
+ import { components } from "../api";
9
+ import { logger } from "../logger";
8
10
  import {
9
11
  ApiConnection,
12
+ MysqlConnection,
10
13
  PostgresConnection,
11
14
  SnowflakeConnection,
12
- MysqlConnection,
13
15
  } from "./model";
14
- import { components } from "../api";
15
16
 
16
17
  type ApiSchemaName = components["schemas"]["SchemaName"];
17
18
 
@@ -156,7 +157,7 @@ export async function getSchemasForConnection(
156
157
  } finally {
157
158
  snowflakeConn.destroy((error) => {
158
159
  if (error) {
159
- console.error(`Error closing SnowflakeConnection: ${error}`);
160
+ logger.error(`Error closing SnowflakeConnection: ${error}`);
160
161
  }
161
162
  });
162
163
  }
@@ -188,9 +189,9 @@ export async function getTablesForSchema(
188
189
  const [tables] = await dataset.getTables();
189
190
  return tables.map((table) => table.id).filter((id) => id) as string[];
190
191
  } catch (error) {
191
- console.error(
192
- `Error getting tables for BigQuery schema ${schemaName} in connection ${connection.name}:`,
193
- error,
192
+ logger.error(
193
+ `Error getting tables for BigQuery schema ${schemaName} in connection ${connection.name}`,
194
+ { error },
194
195
  );
195
196
  throw new Error(
196
197
  `Failed to get tables for BigQuery schema ${schemaName} in connection ${connection.name}: ${(error as Error).message}`,
@@ -232,7 +233,7 @@ export async function getTablesForSchema(
232
233
  } finally {
233
234
  snowflakeConn.destroy((error) => {
234
235
  if (error) {
235
- console.error(`Error closing SnowflakeConnection: ${error}`);
236
+ logger.error(`Error closing SnowflakeConnection`, { error });
236
237
  }
237
238
  });
238
239
  }
@@ -274,10 +275,9 @@ async function getSnowflakeTables(
274
275
  sqlText: `USE DATABASE ${connInfo?.database} `,
275
276
  complete: (err) => {
276
277
  if (err) {
277
- console.error(
278
- `Error setting database ${connInfo.database}:`,
279
- err,
280
- );
278
+ logger.error(`Error setting database ${connInfo.database}:`, {
279
+ error: err,
280
+ });
281
281
  reject([]);
282
282
  return;
283
283
  }
@@ -293,9 +293,9 @@ async function getSnowflakeTables(
293
293
  binds: [schemaName],
294
294
  complete: (err, _, rows) => {
295
295
  if (err) {
296
- console.error(
296
+ logger.error(
297
297
  `Error fetching tables from ${connInfo.database}:`,
298
- err,
298
+ { error: err },
299
299
  );
300
300
  reject([]);
301
301
  } else {
@@ -320,7 +320,7 @@ async function getSnowflakeSchemas(
320
320
  } else {
321
321
  resolve(
322
322
  rows?.map((row) => {
323
- console.log("row", JSON.stringify(row));
323
+ logger.info("row", { row });
324
324
  return {
325
325
  name: row.name,
326
326
  isDefault: row.isDefault === "Y",
@@ -31,6 +31,7 @@ import {
31
31
  ModelCompilationError,
32
32
  ModelNotFoundError,
33
33
  } from "../errors";
34
+ import { logger } from "../logger";
34
35
  import {
35
36
  MODEL_FILE_SUFFIX,
36
37
  NOTEBOOK_FILE_SUFFIX,
@@ -238,7 +239,7 @@ export class Model {
238
239
  if (this.compilationError) {
239
240
  throw this.compilationError;
240
241
  }
241
- console.log("queryName", queryName, "query", query);
242
+ logger.info("queryName", { queryName, query });
242
243
  let runnable: QueryMaterializer;
243
244
  if (!this.modelMaterializer || !this.modelDef || !this.modelInfo)
244
245
  throw new BadRequestError("Model has no queryable entities.");
@@ -13,6 +13,7 @@ import recursive from "recursive-readdir";
13
13
  import { components } from "../api";
14
14
  import { API_PREFIX } from "../constants";
15
15
  import { PackageNotFoundError } from "../errors";
16
+ import { logger } from "../logger";
16
17
  import {
17
18
  MODEL_FILE_SUFFIX,
18
19
  NOTEBOOK_FILE_SUFFIX,
@@ -116,7 +117,7 @@ export class Package {
116
117
  scheduler,
117
118
  );
118
119
  } catch (error) {
119
- console.error(error);
120
+ logger.error("Error loading package", { error });
120
121
  const endTime = performance.now();
121
122
  const executionTime = endTime - startTime;
122
123
  this.packageLoadHistogram.record(executionTime, {
@@ -219,7 +220,7 @@ export class Package {
219
220
  try {
220
221
  files = await recursive(packagePath);
221
222
  } catch (error) {
222
- console.error(error);
223
+ logger.error(error);
223
224
  throw new PackageNotFoundError(
224
225
  `Package config for ${packagePath} does not exist.`,
225
226
  );
@@ -3,6 +3,7 @@ import * as path from "path";
3
3
  import { components } from "../api";
4
4
  import { API_PREFIX } from "../constants";
5
5
  import { ProjectNotFoundError } from "../errors";
6
+ import { logger } from "../logger";
6
7
  import { Project } from "./project";
7
8
  type ApiProject = components["schemas"]["Project"];
8
9
 
@@ -68,9 +69,9 @@ export class ProjectStore {
68
69
  return JSON.parse(projectManifestContent);
69
70
  } catch (error) {
70
71
  if ((error as NodeJS.ErrnoException).code !== "ENOENT") {
71
- // eslint-disable-next-line no-console
72
- console.error(
73
- `Error reading publisher.config.json: ${error.message}. Generating from directory`,
72
+ logger.error(
73
+ `Error reading publisher.config.json. Generating from directory`,
74
+ { error },
74
75
  );
75
76
  return { projects: {} };
76
77
  } else {
@@ -87,10 +88,9 @@ export class ProjectStore {
87
88
  }
88
89
  return { projects };
89
90
  } catch (lsError) {
90
- // eslint-disable-next-line no-console
91
- console.error(
92
- `Error listing directories in ${serverRootPath}: ${lsError.message}`,
93
- );
91
+ logger.error(`Error listing directories in ${serverRootPath}`, {
92
+ error: lsError,
93
+ });
94
94
  return { projects: {} };
95
95
  }
96
96
  }
@@ -1,6 +1,7 @@
1
- import { Model } from "./model";
2
- import { components } from "../api";
3
1
  import cron from "node-cron";
2
+ import { components } from "../api";
3
+ import { logger } from "../logger";
4
+ import { Model } from "./model";
4
5
 
5
6
  type ApiSource = components["schemas"]["Source"];
6
7
  type ApiView = components["schemas"]["View"];
@@ -72,7 +73,7 @@ class Schedule {
72
73
  // TODO: Don't split quoted strings. Use regex instead of split.
73
74
  const annotationSplit = annotation.split(/\s+/);
74
75
  if (annotationSplit.length != 6) {
75
- console.log("Length: " + annotationSplit.length);
76
+ logger.info("Length: " + annotationSplit.length);
76
77
  throw new Error(
77
78
  "Invalid annotation string does not have enough parts: " +
78
79
  annotation,