AgentSkillsCN

Backend Logging

适用于应用和工作进程的后端日志记录

SKILL.md
--- frontmatter
description: Backend logging for app and worker processes
category: Implementation
boundary: Backend (@be/ only)
version: 2.2

Backend Logging

Structured logging for be/ using Pino (app) and Winston (workers).

Setup

App logger is in be/core/utils/logger.ts (Pino). Initialized once in be/core/index.ts. Worker logger is in be/core/utils/winston-worker-logger.ts (Winston).

Rule: Never use console.log (even for quick user/debug checks). Use the logger helpers. Pino covers all app logs; Winston is for worker-layer logs.

Log Types

TypeLayerExample
INFRASTRUCTUREPrisma, pools, startupServer start
REPODatabase accessStoreRepository.create
SERVICEBusiness logicStoreService.createStore
ROUTERHTTP controllersStoreRouter.createStore

Log Levels

LevelWhen
INFONormal operations
ERRORFailures, exceptions
WARNSuspicious but non-fatal
DEBUGVerbose diagnostics (dev only)
FATALUnrecoverable errors

Service Logging Rule

  • Service layer logs should only emit ERROR entries. Avoid INFO logs in services.

Helpers

GeneralLogger

For cross-cutting/infrastructure logs:

typescript
import { GeneralLogger, LogType, LogLevel } from "@Ciri/utils/logger";

GeneralLogger(LogType.INFRASTRUCTURE, LogLevel.INFO, "Prisma client initialized");

UnitLogger

For scoped logs (router/service/repo):

typescript
import { UnitLogger, LogType, LogLevel } from "@Ciri/utils/logger";

UnitLogger(LogType.SERVICE, "StoreService.createStore", LogLevel.INFO, `Creating store for userId=${userId}`);

Worker Logger (Winston)

For BullMQ workers:

typescript
import { createWorkerLogger, logWorkerInfo, WorkerLogLevel } from "@Ciri/utils/winston-worker-logger";

const logger = createWorkerLogger("image-processing", job);
logWorkerInfo(logger, "Worker started");
logger.log(WorkerLogLevel.ERROR, "Image processing failed", { jobId: job.id });

Patterns

Router Layer

typescript
router.post("/createStore", async (req, res, next) => {
  try {
    // ... logic
  } catch (error) {
    UnitLogger(LogType.ROUTER, "StoreRouter.createStore", LogLevel.ERROR, error.message);
    next(error);
  }
});

Service Layer

typescript
async createStore(userId: string, name: string) {
  const store = await this.storeRepo.create({ name });
  return store;
}

Repository Layer

typescript
async create(data: Prisma.StoreCreateInput) {
  UnitLogger(LogType.REPO, "StoreRepository.create", LogLevel.DEBUG, "Creating store");
  return prisma.store.create({ data });
}

Unit Name Convention

  • Router: StoreRouter.createStore
  • Service: StoreService.createStore
  • Repository: StoreRepository.create

Environment

  • DEBUG logs only show when ENVIRONMENT=dev
  • In production, debug logs are skipped