Demo

Logger

Inject the platform logger on services and controllers with property decorators. Prefer @InjectBuiltinLogger for the standard BuiltinLogger.

Usage

Property injection only — never put logger decorators on a constructor parameter. The host class must be DI-managed (@Service or a @Controller registered on the module).

  • Log important operations and lifecycle events (seed skip/complete, job start/finish, uninstall cleanup)
  • Include enough context to debug (ids, plugin name) — not full request bodies with secrets
  • Do not log passwords, tokens, API keys, or other sensitive fields
  • Prefer @InjectBuiltinLogger over a custom console wrapper
  • Pair with @AuditLogMiddleware for user-facing admin actions — logger is for process/runtime diagnostics
TSXservice
1import { InjectBuiltinLogger, Service } from "@quan-erp/shared-backend-core"; 2import type { Loggable } from "@quan-erp/shared-backend-core"; 3 4@Service() 5export class OrderService { 6 @InjectBuiltinLogger() 7 logger: Loggable; 8 9 async create() { 10 this.logger.log("Creating order"); 11 // … 12 this.logger.log("Order created"); 13 } 14}
TSXseed feedback
1import { 2 InjectBuiltinLogger, 3 OnInit, 4 Service, 5} from "@quan-erp/shared-backend-core"; 6import type { Loggable } from "@quan-erp/shared-backend-core"; 7 8@Service() 9export class SeedService { 10 @InjectBuiltinLogger() 11 logger: Loggable; 12 13 @OnInit() 14 async init() { 15 if (alreadySeeded) { 16 this.logger.log("Seeding skipped (already initialized)"); 17 return; 18 } 19 // … seed … 20 this.logger.log("Module seeded successfully"); 21 } 22}

Builtin logger

@InjectBuiltinLogger() is shorthand for @InjectLogger(BuiltinLogger). Type the property as Loggable (or BuiltinLogger). Works on services and controllers.

  • @InjectBuiltinLogger() — inject the platform BuiltinLogger
  • Import from @quan-erp/shared-backend-core
  • Keep messages short and searchable (include plugin/job names)
TSXbuiltin
1import { 2 BuiltinLogger, 3 InjectBuiltinLogger, 4 InjectLogger, 5 Service, 6} from "@quan-erp/shared-backend-core"; 7import type { Loggable } from "@quan-erp/shared-backend-core"; 8 9@Service() 10export class OrderService { 11 @InjectBuiltinLogger() 12 logger: Loggable; 13 14 // equivalent 15 @InjectLogger(BuiltinLogger) 16 builtinLogger: BuiltinLogger; 17}

Creating custom logger

Implement Loggable (or your own logger API), mark it @Service(), register it on the plugin @Module providers, then inject with @InjectLogger(YourLogger). Prefer BuiltinLogger unless you need custom formatting or sinks.

  • 1. Define a @Service() class that implements Loggable (log / error / …)
  • 2. Add the class to @Module({ providers: [...] })
  • 3. Inject with property @InjectLogger(MyPluginLogger) — never constructor injection
TSXmy-plugin.logger.ts
1import { Service } from "@quan-erp/shared-backend-core"; 2import type { Loggable } from "@quan-erp/shared-backend-core"; 3 4@Service() 5export class MyPluginLogger implements Loggable { 6 private prefix = "[my-plugin]"; 7 8 log(message: string, ...args: unknown[]) { 9 console.log(this.prefix, message, ...args); 10 } 11 12 error(message: string, ...args: unknown[]) { 13 console.error(this.prefix, message, ...args); 14 } 15 16 warn(message: string, ...args: unknown[]) { 17 console.warn(this.prefix, message, ...args); 18 } 19}
TSXmodule providers
1import { Module } from "@quan-erp/shared-backend-core"; 2import { OrderController } from "./order.controller.js"; 3import { OrderService } from "./order.service.js"; 4import { MyPluginLogger } from "./my-plugin.logger.js"; 5 6@Module({ 7 name: "my-plugin", 8 providers: [OrderService, MyPluginLogger], 9 controllers: [OrderController], 10 entities: [], 11}) 12export class MyPluginModule {}
TSXinject & use
1import { InjectLogger, Service } from "@quan-erp/shared-backend-core"; 2import { MyPluginLogger } from "./my-plugin.logger.js"; 3 4@Service() 5export class OrderService { 6 @InjectLogger(MyPluginLogger) 7 logger: MyPluginLogger; 8 9 async create(orderId: string) { 10 this.logger.log(`Creating order ${orderId}`); 11 try { 12 // … 13 this.logger.log(`Order ${orderId} created`); 14 } catch (err) { 15 this.logger.error(`Failed to create order ${orderId}`, err); 16 throw err; 17 } 18 } 19}