{
  "title": "استاندارد لاگ‌نویسی",
  "slug": "team/platform/standards/logging-standard",
  "url": "/docs/team/platform/standards/logging-standard",
  "frontmatter": {
    "layout": "doc",
    "title": "استاندارد لاگ‌نویسی",
    "description": "JSON ساختاریافته، سطوح لاگ، فیلدهای اجباری و قوانین PII",
    "version": "1.0.0",
    "status": "PRIVATE",
    "author": "xoxxel",
    "owner": "xoxxel",
    "created_at": "2026-06-07",
    "updated_at": "2026-06-07",
    "tags": "",
    "reviewers": ""
  },
  "sections": [
    {
      "level": 1,
      "heading": "استاندارد لاگ‌نویسی",
      "content": "**Logging Standard**\n\nنسخه 1.0 | الزامی برای همه سرویس‌ها\n\n> **تفکیک قرارداد از پیاده‌سازی:**  \n> این سند **قرارداد (Logging Contract)** را تعریف می‌کند — یعنی لاگ‌ها **باید** چه ساختاری داشته باشند.  \n> این بخش تنها قرارداد، ساختار و فیلدهای اجباری را تعریف می‌کند.  \n> **پیاده‌سازی لاگر نیست** — انتخاب کتابخانه و نحوه پیاده‌سازی لاگر (Logger Implementation) **آزاد** است.  \n> پیشنهاد: Go ← `slog`، Node.js ← `pino`، Python ← `structlog`  \n> قرارداد نهایی در `nons-api/packages/logging` به صورت types و interfaces پیاده‌سازی می‌شود. هیچ پیاده‌سازی اجرایی در این پکیج وجود ندارد.\n> **نکته:** Logging Contract خارج از محدوده ADR-Platform-001 است و به Proto مهاجرت نمی‌کند. این یک قرارداد استاندارد خروجی است، نه قرارداد انتقال داده بین سرویس‌ها.\n\n---"
    },
    {
      "level": 2,
      "heading": "Log Contract (قرارداد ثبت وقایع)",
      "content": ""
    },
    {
      "level": 3,
      "heading": "1. منطق قرارداد",
      "content": "هر لاگ یک **شی JSON** است با ساختار زیر. این قرارداد بین همه سرویس‌ها الزامی است.\n\n```typescript\n// قرارداد LogEntry — مبنای اعتبارسنجی همه لاگ‌ها\ninterface LogEntry {\n  // MUST — همیشه وجود داشته باشد\n  level: \"debug\" | \"info\" | \"warn\" | \"error\";\n  timestamp: string; // ISO 8601 UTC, مثال: \"2024-01-01T12:00:00.000Z\"\n  service: string; // نام سرویس, مثال: \"order-service\"\n  traceId: string; // شناسه یکتای ردیابی — MUST در همه لاگ‌ها\n  message: string; // پیام انگلیسی, بدون placeholder\n\n  // SHOULD — در صورت وجود، الزامات زیر را رعایت کند\n  context?: Record<string, unknown>; // داده‌های ساختاریافته, بدون PII\n  error?: {\n    // فقط در سطح error\n    code: string; // کد خطای یکپارچه\n    message: string; // پیام خطا\n    stack?: string; // stack trace (فقط در توسعه)\n  };\n\n  // MUST NOT — هرگز وجود نداشته باشد\n  // email, phone, name, password, token, secret, creditCard\n}\n```"
    },
    {
      "level": 3,
      "heading": "2. فیلدهای قرارداد",
      "content": "| فیلد                | سطح الزام                | نوع                                   | اعتبارسنجی                                                   | مثال                                                 |\n| ------------------- | ------------------------ | ------------------------------------- | ------------------------------------------------------------ | ---------------------------------------------------- |\n| `level`             | **MUST**                 | `enum(\"debug\",\"info\",\"warn\",\"error\")` | یکی از ۴ مقدار مجاز                                          | `\"info\"`                                             |\n| `timestamp`         | **MUST**                 | `string`                              | الگوی `ISO 8601 UTC` با پسوند Z                              | `\"2024-01-01T12:00:00.000Z\"`                         |\n| `service`           | **MUST**                 | `string`                              | نام سرویس مطابق با repository-structure                      | `\"order-service\"`                                    |\n| `traceId`           | **MUST**                 | `string`                              | شناسه ردیابی — propagate شده از درخواست اولیه                | `\"trace_abc123def456\"`                               |\n| `message`           | **MUST**                 | `string`                              | حداکثر ۲۰۰ کاراکتر، انگلیسی، بدون interpolated data          | `\"Order created successfully\"`                       |\n| `context`           | **SHOULD**               | `object`                              | بدون PII، بدون توکن/رمز                                      | `{ \"orderId\": \"...\", \"amount\": 150 }`                |\n| `error`             | **SHOULD** (error level) | `object`                              | فقط در سطح `error`                                           | `{ \"code\": \"ESCROW_LOCK_FAILED\", \"message\": \"...\" }` |\n| ~~`correlationId`~~ | ~~**MUST**~~             | ~~`string`~~                          | **منسوخ (Deprecated)** — به جای آن از `traceId` استفاده کنید | —                                                    |\n\n> **MUST** = الزامی - رعایت نشدن مساوی نقض قرارداد  \n> **SHOULD** = توصیه‌شده - در صورت وجود باید مطابق استاندارد باشد  \n> **MUST NOT** = ممنوع - لاگ حاوی این مقادیر مردود است"
    },
    {
      "level": 3,
      "heading": "3. خروجی مورد انتظار (Expected Output)",
      "content": "هر سرویس باید لاگ‌هایی با **دقیقاً** این ساختار تولید کند:\n\n```json\n{\n  \"level\": \"info\",\n  \"timestamp\": \"2024-01-01T12:00:00.000Z\",\n  \"service\": \"order-service\",\n  \"traceId\": \"trace_abc123def456\",\n  \"message\": \"Order created successfully\",\n  \"context\": {\n    \"orderId\": \"018e1234-...\",\n    \"sellerId\": \"018e1234-...\",\n    \"amount\": 150.0\n  }\n}\n```\n\n**خطا:**\n\n```json\n{\n  \"level\": \"error\",\n  \"timestamp\": \"2024-01-01T12:00:00.000Z\",\n  \"service\": \"order-service\",\n  \"traceId\": \"trace_abc123def456\",\n  \"message\": \"Failed to process order payment\",\n  \"context\": {\n    \"orderId\": \"018e1234-...\"\n  },\n  \"error\": {\n    \"code\": \"ESCROW_LOCK_FAILED\",\n    \"message\": \"Insufficient balance\",\n    \"stack\": \"at PaymentService.lock (payment.ts:42)\"\n  }\n}\n```\n\n---"
    },
    {
      "level": 2,
      "heading": "4. سطوح لاگ (Log Levels)",
      "content": "| سطح     | مقدار `level` | الزام              | زمان استفاده                    |\n| ------- | ------------- | ------------------ | ------------------------------- |\n| `debug` | `\"debug\"`     | SHOULD (فقط توسعه) | جزئیات عیب‌یابی — هرگز در تولید |\n| `info`  | `\"info\"`      | MUST               | رویدادهای عادی کسب‌وکار         |\n| `warn`  | `\"warn\"`      | MUST               | غیرمنتظره اما قابل بازیابی      |\n| `error` | `\"error\"`     | MUST               | شکست‌هایی که نیاز به توجه دارند |\n\n```typescript\n// ✅ مطابق قرارداد\nlogger.info(\"Order created\", { orderId, sellerId, amount });\nlogger.warn(\"Payment gateway timeout\", { orderId, retryCount: 3 });\nlogger.error(\"Failed to release escrow\", { orderId, error: err.message });\n\n// ❌ نقض قرارداد\nlogger.log(\"Order created\"); // بدون level\nconsole.log(\"Order created\", orderId); // بدون ساختار JSON\nlogger.info(`Order ${orderId} created`); // interpolated data در message\n```\n\n---"
    },
    {
      "level": 2,
      "heading": "5. قوانین قرارداد",
      "content": "| قانون                      | سطح الزام | توضیح                                                             |\n| -------------------------- | --------- | ----------------------------------------------------------------- |\n| **JSON ساختاریافته**       | MUST      | همه لاگ‌ها در تولید JSON باشند                                    |\n| **همه فیلدهای MUST**       | MUST      | وجود `level`, `timestamp`, `service`, `traceId`, `message` الزامی |\n| **بدون PII**               | MUST NOT  | ایمیل، تلفن، نام، آدرس، اطلاعات پرداخت ممنوع                      |\n| **بدون رمز/توکن**          | MUST NOT  | password, token, secret, apiKey, creditCard ممنوع                 |\n| **message بدون داده**      | MUST      | داده‌ها در `context` قرار گیرند، نه درون `message`                |\n| **UTC timestamp**          | MUST      | همه timestampها با پسوند Z                                        |\n| **debug غیرفعال در تولید** | SHOULD    | با متغیر `LOG_LEVEL` کنترل شود                                    |\n| **خطا شامل error object**  | SHOULD    | خطاهای `error` level شامل `code` و `message`                      |\n\n```typescript\n// ✅ مطابق قرارداد — بدون PII\nlogger.info(\"User registered\", { userId, role });\n\n// ❌ نقض قرارداد — شامل PII\nlogger.info(\"User registered\", { email: \"user@example.com\", phone: \"0912...\" });\n\n// ❌ نقض قرارداد — شامل رمز\nlogger.info(\"Login successful\", { password: \"12345\" });\n```\n\n---"
    },
    {
      "level": 2,
      "heading": "6. Logger Implementation (پیاده‌سازی)",
      "content": "انتخاب کتابخانه لاگر **آزاد** است. جدول زیر صرفاً پیشنهاد است:\n\n| زبان               | کتابخانه پیشنهادی       |\n| ------------------ | ----------------------- |\n| Go                 | `slog`, `zap`, `logrus` |\n| TypeScript/Node.js | `pino`, `winston`       |\n| Python             | `structlog`, `loguru`   |\n\n> هر کتابخانه‌ای که انتخاب شود، خروجی نهایی **باید** با Log Contract تعریف‌شده در بخش‌های ۱-۳ مطابقت داشته باشد.\n\n---"
    },
    {
      "level": 2,
      "heading": "7. پیکربندی",
      "content": "| متغیر محیط  | مقدار پیش‌فرض | توضیح                                           |\n| ----------- | ------------- | ----------------------------------------------- |\n| `LOG_LEVEL` | `info`        | فیلتر سطح لاگ: `debug`, `info`, `warn`, `error` |\n\n```bash"
    },
    {
      "level": 1,
      "heading": "توسعه محلی — همه لاگ‌ها",
      "content": "LOG_LEVEL=debug"
    },
    {
      "level": 1,
      "heading": "تولید — رویدادها، هشدارها و خطاها",
      "content": "LOG_LEVEL=info\n```\n\n---"
    },
    {
      "level": 2,
      "heading": "خلاصه قرارداد",
      "content": "| مورد            | سطح الزام | قانون                                                 |\n| --------------- | --------- | ----------------------------------------------------- |\n| فرمت            | MUST      | JSON ساختاریافته                                      |\n| فیلدهای MUST    | MUST      | `level`, `timestamp`, `service`, `traceId`, `message` |\n| فیلدهای SHOULD  | SHOULD    | `context`, `error`                                    |\n| PII             | MUST NOT  | ایمیل، تلفن، نام، اطلاعات پرداخت ممنوع                |\n| رمز/توکن        | MUST NOT  | هرگز لاگ نشود                                         |\n| سطوح مجاز       | MUST      | فقط `debug`, `info`, `warn`, `error`                  |\n| داده در context | MUST      | `message` بدون interpolated data                      |\n| خطاها           | SHOULD    | شامل `error.code` و `error.message`                   |"
    }
  ]
}