logixia 1.13.3 → 2.0.4
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/README.md +117 -44
- package/dist/async-context-B05ArHgM.mjs +134 -0
- package/dist/async-context-B05ArHgM.mjs.map +1 -0
- package/dist/async-context-DTQgi8f7.js +150 -0
- package/dist/async-context-DTQgi8f7.js.map +1 -0
- package/dist/{azure-monitor.transport-CHnjVRF-.mjs → azure-monitor.transport-BPbgjATu.mjs} +27 -15
- package/dist/azure-monitor.transport-BPbgjATu.mjs.map +1 -0
- package/dist/{azure-monitor.transport-BDFO4F-i.d.ts → azure-monitor.transport-C7kYyZUW.d.mts} +3 -6
- package/dist/azure-monitor.transport-C7kYyZUW.d.mts.map +1 -0
- package/dist/{azure-monitor.transport-CrvfHd9C.js → azure-monitor.transport-CwbOLZHB.js} +32 -20
- package/dist/azure-monitor.transport-CwbOLZHB.js.map +1 -0
- package/dist/{azure-monitor.transport-D5wQEH04.d.mts → azure-monitor.transport-DV03Z5P4.d.ts} +3 -6
- package/dist/azure-monitor.transport-DV03Z5P4.d.ts.map +1 -0
- package/dist/azure.d.mts +1 -2
- package/dist/azure.d.ts +1 -2
- package/dist/azure.js +3 -6
- package/dist/azure.mjs +1 -6
- package/dist/{batch-buffer-PGvSgbmd.mjs → batch-buffer-0fgLmIPn.mjs} +21 -7
- package/dist/batch-buffer-0fgLmIPn.mjs.map +1 -0
- package/dist/{batch-buffer-BY-mRWIK.js → batch-buffer-DT4gdXmf.js} +53 -40
- package/dist/batch-buffer-DT4gdXmf.js.map +1 -0
- package/dist/browser.d.mts +52 -23
- package/dist/browser.d.mts.map +1 -1
- package/dist/browser.d.ts +52 -23
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +460 -62
- package/dist/browser.js.map +1 -1
- package/dist/browser.mjs +461 -65
- package/dist/browser.mjs.map +1 -1
- package/dist/{nestjs-extras-ImbuDhs1.mjs → builder-D70z6kjj.mjs} +279 -965
- package/dist/builder-D70z6kjj.mjs.map +1 -0
- package/dist/{nestjs-extras-DnJ6vrIC.js → builder-M7NoaugM.js} +421 -1177
- package/dist/builder-M7NoaugM.js.map +1 -0
- package/dist/cli/index.js +86 -67
- package/dist/cloudwatch.d.mts +1 -2
- package/dist/cloudwatch.d.ts +1 -2
- package/dist/cloudwatch.js +3 -7
- package/dist/cloudwatch.mjs +1 -7
- package/dist/{cloudwatch.transport-BO1ahxw-.js → cloudwatch.transport-B2wKQFF7.js} +61 -36
- package/dist/cloudwatch.transport-B2wKQFF7.js.map +1 -0
- package/dist/{cloudwatch.transport-DZ6ies7g.mjs → cloudwatch.transport-BTvYfLs9.mjs} +54 -28
- package/dist/cloudwatch.transport-BTvYfLs9.mjs.map +1 -0
- package/dist/{cloudwatch.transport-B00st6Xv.d.ts → cloudwatch.transport-Bf7L4I59.d.ts} +2 -6
- package/dist/cloudwatch.transport-Bf7L4I59.d.ts.map +1 -0
- package/dist/{cloudwatch.transport-Blc7Gtxt.d.mts → cloudwatch.transport-Rj4yTpRn.d.mts} +2 -6
- package/dist/cloudwatch.transport-Rj4yTpRn.d.mts.map +1 -0
- package/dist/{coerce.utils-Cu6IUTgX.mjs → coerce.utils-B_rEudCn.mjs} +3 -4
- package/dist/{coerce.utils-Cu6IUTgX.mjs.map → coerce.utils-B_rEudCn.mjs.map} +1 -1
- package/dist/{coerce.utils-B-LilukN.js → coerce.utils-C1C5sIX0.js} +8 -10
- package/dist/{coerce.utils-B-LilukN.js.map → coerce.utils-C1C5sIX0.js.map} +1 -1
- package/dist/correlation.d.mts +13 -16
- package/dist/correlation.d.mts.map +1 -1
- package/dist/correlation.d.ts +13 -16
- package/dist/correlation.d.ts.map +1 -1
- package/dist/correlation.js +58 -9
- package/dist/correlation.js.map +1 -1
- package/dist/correlation.mjs +56 -6
- package/dist/correlation.mjs.map +1 -1
- package/dist/{entry-fields-BJkuPnIg.mjs → entry-fields-CGuvT2R0.mjs} +5 -6
- package/dist/entry-fields-CGuvT2R0.mjs.map +1 -0
- package/dist/{entry-fields-BvOLFlJ4.js → entry-fields-RLd1jCoR.js} +10 -12
- package/dist/entry-fields-RLd1jCoR.js.map +1 -0
- package/dist/gcp.d.mts +1 -2
- package/dist/gcp.d.ts +1 -2
- package/dist/gcp.js +3 -7
- package/dist/gcp.mjs +1 -7
- package/dist/{gcp.transport-m4fVw0b1.d.ts → gcp.transport-C5D72b1g.d.mts} +3 -6
- package/dist/gcp.transport-C5D72b1g.d.mts.map +1 -0
- package/dist/{gcp.transport-zzNyIoih.d.mts → gcp.transport-CFQfdAOK.d.ts} +3 -6
- package/dist/gcp.transport-CFQfdAOK.d.ts.map +1 -0
- package/dist/{gcp.transport-DBX5TPIy.mjs → gcp.transport-CGKopAhQ.mjs} +55 -16
- package/dist/gcp.transport-CGKopAhQ.mjs.map +1 -0
- package/dist/{gcp.transport-CHV8MGgz.js → gcp.transport-KZe9hCAR.js} +60 -22
- package/dist/gcp.transport-KZe9hCAR.js.map +1 -0
- package/dist/{index-nZEeCr3X.d.ts → index-DwozbmB4.d.ts} +3 -8
- package/dist/index-DwozbmB4.d.ts.map +1 -0
- package/dist/{index-BPwEisy4.d.mts → index-xqaJtAZn.d.mts} +3 -8
- package/dist/index-xqaJtAZn.d.mts.map +1 -0
- package/dist/index.d.mts +141 -203
- package/dist/index.d.mts.map +1 -1
- package/dist/index.d.ts +140 -202
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +196 -381
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +145 -294
- package/dist/index.mjs.map +1 -1
- package/dist/internal-log-b0Vp4qrB.js +183 -0
- package/dist/internal-log-b0Vp4qrB.js.map +1 -0
- package/dist/internal-log-uCSd1PMc.mjs +142 -0
- package/dist/internal-log-uCSd1PMc.mjs.map +1 -0
- package/dist/logitron-logger-D2B75Oc7.d.ts +365 -0
- package/dist/logitron-logger-D2B75Oc7.d.ts.map +1 -0
- package/dist/logitron-logger-oEd6wNhf.d.mts +365 -0
- package/dist/logitron-logger-oEd6wNhf.d.mts.map +1 -0
- package/dist/middleware.d.mts +10 -12
- package/dist/middleware.d.mts.map +1 -1
- package/dist/middleware.d.ts +10 -12
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +16 -47
- package/dist/middleware.js.map +1 -1
- package/dist/middleware.mjs +13 -45
- package/dist/middleware.mjs.map +1 -1
- package/dist/nest.d.mts +467 -10
- package/dist/nest.d.mts.map +1 -1
- package/dist/nest.d.ts +467 -10
- package/dist/nest.d.ts.map +1 -1
- package/dist/nest.js +889 -43
- package/dist/nest.js.map +1 -0
- package/dist/nest.mjs +850 -9
- package/dist/nest.mjs.map +1 -0
- package/dist/{trace.utils-CvXgaiQT.mjs → request-trace-C_fvIDv4.mjs} +44 -9
- package/dist/request-trace-C_fvIDv4.mjs.map +1 -0
- package/dist/{trace.utils-DpBOLDtq.js → request-trace-wTJdKp6-.js} +121 -77
- package/dist/request-trace-wTJdKp6-.js.map +1 -0
- package/dist/rolldown-runtime-D3PmRqjj.mjs +4 -0
- package/dist/{safe-stringify-DJ66tW5I.mjs → safe-stringify-BMRl3EX3.mjs} +3 -4
- package/dist/safe-stringify-BMRl3EX3.mjs.map +1 -0
- package/dist/{safe-stringify-DWo3aZp_.js → safe-stringify-DLz1Kz3o.js} +23 -25
- package/dist/safe-stringify-DLz1Kz3o.js.map +1 -0
- package/dist/{search-CHUZPl0h.d.ts → search-BH33XhuU.d.mts} +2 -22
- package/dist/search-BH33XhuU.d.mts.map +1 -0
- package/dist/{search-DjXSn6v5.mjs → search-CWMVYC-R.mjs} +34 -41
- package/dist/search-CWMVYC-R.mjs.map +1 -0
- package/dist/{search-BfBzDIT9.d.mts → search-CazwyX5Z.d.ts} +2 -22
- package/dist/search-CazwyX5Z.d.ts.map +1 -0
- package/dist/{search-B0MH1SJJ.js → search-DUfWuzFP.js} +64 -71
- package/dist/search-DUfWuzFP.js.map +1 -0
- package/dist/search.d.mts +2 -4
- package/dist/search.d.ts +2 -4
- package/dist/search.js +3 -4
- package/dist/search.mjs +1 -4
- package/dist/secret-config-BegMLkYl.mjs +209 -0
- package/dist/secret-config-BegMLkYl.mjs.map +1 -0
- package/dist/secret-config-CBZBs0p1.js +271 -0
- package/dist/secret-config-CBZBs0p1.js.map +1 -0
- package/dist/slack.transport-Ce96JBDk.mjs +824 -0
- package/dist/slack.transport-Ce96JBDk.mjs.map +1 -0
- package/dist/slack.transport-Dlx3xvb7.js +847 -0
- package/dist/slack.transport-Dlx3xvb7.js.map +1 -0
- package/dist/slack.transport-DrirgDNy.d.ts +159 -0
- package/dist/slack.transport-DrirgDNy.d.ts.map +1 -0
- package/dist/slack.transport-DxHOXlLu.d.mts +159 -0
- package/dist/slack.transport-DxHOXlLu.d.mts.map +1 -0
- package/dist/testing.d.mts +3 -8
- package/dist/testing.d.mts.map +1 -1
- package/dist/testing.d.ts +3 -8
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +3 -4
- package/dist/testing.js.map +1 -1
- package/dist/testing.mjs +2 -3
- package/dist/testing.mjs.map +1 -1
- package/dist/{transport.manager-Crau3Rle.js → transport.manager-DkcEOlqV.js} +331 -234
- package/dist/transport.manager-DkcEOlqV.js.map +1 -0
- package/dist/{transport.manager-CpdVHEGP.mjs → transport.manager-eZ_EeC00.mjs} +274 -178
- package/dist/transport.manager-eZ_EeC00.mjs.map +1 -0
- package/dist/{transport.types-CtNr3D7S.d.mts → transport.types-BJVL1QQl.d.mts} +5 -4
- package/dist/transport.types-BJVL1QQl.d.mts.map +1 -0
- package/dist/{transport.types-DqVLZTyf.d.ts → transport.types-BJVL1QQl.d.ts} +5 -4
- package/dist/transport.types-BJVL1QQl.d.ts.map +1 -0
- package/dist/transports.d.mts +32 -41
- package/dist/transports.d.mts.map +1 -1
- package/dist/transports.d.ts +32 -41
- package/dist/transports.d.ts.map +1 -1
- package/dist/transports.js +12 -12
- package/dist/transports.mjs +7 -12
- package/dist/worker-entry.js +337 -87
- package/dist/worker.d.mts +1 -2
- package/dist/worker.d.ts +1 -2
- package/dist/worker.js +3 -4
- package/dist/worker.mjs +1 -4
- package/dist/{worker.transport-Bj-i0P9V.d.ts → worker.transport-BuPwBi3d.d.ts} +2 -6
- package/dist/worker.transport-BuPwBi3d.d.ts.map +1 -0
- package/dist/{worker.transport-JP8YHBuU.js → worker.transport-C6GNl_r2.js} +44 -14
- package/dist/worker.transport-C6GNl_r2.js.map +1 -0
- package/dist/{worker.transport-otwhJ_Et.mjs → worker.transport-DLVA4y2e.mjs} +39 -9
- package/dist/worker.transport-DLVA4y2e.mjs.map +1 -0
- package/dist/{worker.transport-Bgv9heDI.d.mts → worker.transport-hJay1wxA.d.mts} +2 -6
- package/dist/worker.transport-hJay1wxA.d.mts.map +1 -0
- package/package.json +36 -19
- package/dist/async-context-BzJrbfQs.mjs +0 -72
- package/dist/async-context-BzJrbfQs.mjs.map +0 -1
- package/dist/async-context-DyQQYq3I.js +0 -92
- package/dist/async-context-DyQQYq3I.js.map +0 -1
- package/dist/azure-monitor.transport-BDFO4F-i.d.ts.map +0 -1
- package/dist/azure-monitor.transport-CHnjVRF-.mjs.map +0 -1
- package/dist/azure-monitor.transport-CrvfHd9C.js.map +0 -1
- package/dist/azure-monitor.transport-D5wQEH04.d.mts.map +0 -1
- package/dist/batch-buffer-BY-mRWIK.js.map +0 -1
- package/dist/batch-buffer-PGvSgbmd.mjs.map +0 -1
- package/dist/chunk-DLSkYcPk.mjs +0 -7
- package/dist/chunk-nOFOJqeH.js +0 -30
- package/dist/cloudwatch.transport-B00st6Xv.d.ts.map +0 -1
- package/dist/cloudwatch.transport-BO1ahxw-.js.map +0 -1
- package/dist/cloudwatch.transport-Blc7Gtxt.d.mts.map +0 -1
- package/dist/cloudwatch.transport-DZ6ies7g.mjs.map +0 -1
- package/dist/entry-fields-BJkuPnIg.mjs.map +0 -1
- package/dist/entry-fields-BvOLFlJ4.js.map +0 -1
- package/dist/gcp.transport-CHV8MGgz.js.map +0 -1
- package/dist/gcp.transport-DBX5TPIy.mjs.map +0 -1
- package/dist/gcp.transport-m4fVw0b1.d.ts.map +0 -1
- package/dist/gcp.transport-zzNyIoih.d.mts.map +0 -1
- package/dist/index-BPwEisy4.d.mts.map +0 -1
- package/dist/index-nZEeCr3X.d.ts.map +0 -1
- package/dist/internal-log-BUJYMZbE.js +0 -70
- package/dist/internal-log-BUJYMZbE.js.map +0 -1
- package/dist/internal-log-Cm8SOWSV.mjs +0 -52
- package/dist/internal-log-Cm8SOWSV.mjs.map +0 -1
- package/dist/nestjs-extras-DnJ6vrIC.js.map +0 -1
- package/dist/nestjs-extras-ImbuDhs1.mjs.map +0 -1
- package/dist/nestjs-extras-OkC796py.d.mts +0 -725
- package/dist/nestjs-extras-OkC796py.d.mts.map +0 -1
- package/dist/nestjs-extras-mKrHE9S6.d.ts +0 -725
- package/dist/nestjs-extras-mKrHE9S6.d.ts.map +0 -1
- package/dist/safe-stringify-DJ66tW5I.mjs.map +0 -1
- package/dist/safe-stringify-DWo3aZp_.js.map +0 -1
- package/dist/search-B0MH1SJJ.js.map +0 -1
- package/dist/search-BfBzDIT9.d.mts.map +0 -1
- package/dist/search-CHUZPl0h.d.ts.map +0 -1
- package/dist/search-DjXSn6v5.mjs.map +0 -1
- package/dist/trace.utils-CvXgaiQT.mjs.map +0 -1
- package/dist/trace.utils-DpBOLDtq.js.map +0 -1
- package/dist/transport.manager-CpdVHEGP.mjs.map +0 -1
- package/dist/transport.manager-Crau3Rle.js.map +0 -1
- package/dist/transport.types-CtNr3D7S.d.mts.map +0 -1
- package/dist/transport.types-DqVLZTyf.d.ts.map +0 -1
- package/dist/worker.transport-Bgv9heDI.d.mts.map +0 -1
- package/dist/worker.transport-Bj-i0P9V.d.ts.map +0 -1
- package/dist/worker.transport-JP8YHBuU.js.map +0 -1
- package/dist/worker.transport-otwhJ_Et.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"azure-monitor.transport-CrvfHd9C.js","names":["SEVERITY_MAP: Record<string, number>","DEFAULT_REQUEST_TIMEOUT_MS","BatchBuffer","DEFAULT_MAX_BUFFER_SIZE","stringifyForLog","httpRequest","reqUrl: URL"],"sources":["../src/transports/azure-monitor.transport.ts"],"sourcesContent":["/**\n * logixia — Azure Monitor / Application Insights transport\n *\n * Sends log entries to Azure Monitor via the Data Collection Rules (DCR) API\n * using the Logs Ingestion API (the modern replacement for the legacy HTTP\n * Data Collector API).\n *\n * Maps logixia levels to Application Insights severity levels:\n * verbose → 0, debug → 1, info → 1, warn → 2, error → 3, critical → 4\n *\n * @example\n * ```ts\n * import { AzureMonitorTransport } from 'logixia';\n *\n * const logger = createLogger({\n * transports: {\n * azure: new AzureMonitorTransport({\n * // Logs Ingestion API endpoint (from your DCR)\n * endpoint: 'https://<dce>.ingest.monitor.azure.com',\n * ruleId: 'dcr-xxxxxxxxxxxxxxxx',\n * streamName: 'Custom-LogixiaLogs',\n * // Client credentials (or managed identity via no-credential mode)\n * tenantId: process.env.AZURE_TENANT_ID,\n * clientId: process.env.AZURE_CLIENT_ID,\n * clientSecret: process.env.AZURE_CLIENT_SECRET,\n * }),\n * },\n * });\n * ```\n */\n\nimport type { IAsyncTransport, TransportLogEntry } from '../types/transport.types';\nimport { internalError, internalWarn } from '../utils/internal-log';\nimport { stringifyForLog } from '../utils/safe-stringify';\nimport {\n BatchBuffer,\n DEFAULT_MAX_BUFFER_SIZE,\n DEFAULT_REQUEST_TIMEOUT_MS,\n httpRequest,\n} from './batch-buffer';\n\n/**\n * Azure AD tenant IDs are either a GUID or a verified domain (e.g. `contoso.onmicrosoft.com`).\n * This pattern is deliberately permissive on structure but strict on character\n * set — it rejects the breakout characters (`/`, `@`, `:`, `?`, `#`, whitespace)\n * that would let a hostile config smuggle a different host, path, or query into\n * the OAuth token URL.\n */\nconst AZURE_TENANT_RE = /^[a-z0-9][a-z0-9.-]{1,253}$/i;\n\nexport interface AzureMonitorTransportConfig {\n /** DCE (Data Collection Endpoint) URL, e.g. `https://<name>.ingest.monitor.azure.com`. */\n endpoint: string;\n /** Data Collection Rule immutable ID (from Azure portal). */\n ruleId: string;\n /** Stream name defined in the DCR, e.g. `'Custom-LogixiaLogs_CL'`. */\n streamName: string;\n /** Azure AD tenant ID for OAuth2 client-credentials flow. */\n tenantId?: string;\n /** Azure AD app (service principal) client ID. */\n clientId?: string;\n /** Azure AD app client secret. */\n clientSecret?: string;\n /** Number of entries to batch. @default 200 */\n batchSize?: number;\n /** Flush interval in ms. @default 5000 */\n flushIntervalMs?: number;\n /** Abort a request that has not finished after this many ms. @default 10000 */\n requestTimeoutMs?: number;\n /** Max buffered entries; the oldest are dropped past this. @default 10000 */\n maxBufferSize?: number;\n level?: string;\n}\n\nconst SEVERITY_MAP: Record<string, number> = {\n verbose: 0,\n trace: 0,\n debug: 1,\n info: 1,\n log: 1,\n warn: 2,\n warning: 2,\n error: 3,\n critical: 4,\n fatal: 4,\n};\n\n/**\n * Azure Monitor Logs Ingestion transport.\n */\nexport class AzureMonitorTransport implements IAsyncTransport {\n public readonly name = 'azure-monitor';\n public readonly batchSize: number;\n public readonly flushInterval: number;\n public readonly level: string | undefined;\n\n private readonly buffer: BatchBuffer<TransportLogEntry>;\n private readonly requestTimeoutMs: number;\n private flushTimer: NodeJS.Timeout | null = null;\n private accessToken: string | null = null;\n private tokenExpiry = 0;\n\n private readonly endpoint: string;\n private readonly ruleId: string;\n private readonly streamName: string;\n private readonly tenantId: string | undefined;\n private readonly clientId: string | undefined;\n private readonly clientSecret: string | undefined;\n\n constructor(config: AzureMonitorTransportConfig) {\n this.endpoint = config.endpoint.replace(/\\/$/, '');\n this.ruleId = config.ruleId;\n this.streamName = config.streamName;\n this.tenantId = config.tenantId ?? process.env['AZURE_TENANT_ID'];\n this.clientId = config.clientId ?? process.env['AZURE_CLIENT_ID'];\n this.clientSecret = config.clientSecret ?? process.env['AZURE_CLIENT_SECRET'];\n this.batchSize = config.batchSize ?? 200;\n this.flushInterval = config.flushIntervalMs ?? 5000;\n this.level = config.level;\n this.requestTimeoutMs = config.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;\n this.buffer = new BatchBuffer<TransportLogEntry>({\n name: 'AzureMonitorTransport',\n batchSize: this.batchSize,\n maxBufferSize: config.maxBufferSize ?? DEFAULT_MAX_BUFFER_SIZE,\n send: (entries) => this.sendEntries(entries),\n });\n\n this.flushTimer = setInterval(() => {\n this.flush().catch(() => {});\n }, this.flushInterval);\n if (this.flushTimer.unref) this.flushTimer.unref();\n }\n\n write(entry: TransportLogEntry): void {\n this.buffer.push(entry);\n this.buffer.flushIfFull();\n }\n\n flush(): Promise<void> {\n return this.buffer.flush();\n }\n\n /**\n * Flush remaining entries and stop the interval timer on shutdown. Without\n * this the manager's close() skipped the transport (close was undefined) and\n * buffered entries were lost on deploy. Waits for any in-flight send first.\n */\n async close(): Promise<void> {\n if (this.flushTimer) {\n clearInterval(this.flushTimer);\n this.flushTimer = null;\n }\n await this.buffer.close();\n }\n\n private toAzureRecord(entry: TransportLogEntry): Record<string, unknown> {\n return {\n TimeGenerated: entry.timestamp ?? new Date().toISOString(),\n SeverityLevel: SEVERITY_MAP[entry.level.toLowerCase()] ?? 1,\n Message: entry.message,\n AppName: entry.appName,\n Context: entry.context ?? '',\n TraceId: entry.traceId ?? '',\n Properties: stringifyForLog(entry.data ?? {}),\n };\n }\n\n private async getAccessToken(): Promise<string | null> {\n if (this.accessToken && Date.now() < this.tokenExpiry) return this.accessToken;\n\n if (!this.tenantId || !this.clientId || !this.clientSecret) {\n internalWarn(\n 'AzureMonitorTransport: missing credentials — set tenantId, clientId, clientSecret'\n );\n return null;\n }\n\n const body = new URLSearchParams({\n grant_type: 'client_credentials',\n client_id: this.clientId,\n client_secret: this.clientSecret,\n scope: 'https://monitor.azure.com/.default',\n }).toString();\n\n const tenantId = this.tenantId;\n if (!AZURE_TENANT_RE.test(tenantId)) {\n internalWarn(\n `AzureMonitorTransport: refusing to request token — tenantId \"${tenantId}\" is not a valid GUID or domain`\n );\n return null;\n }\n\n const reqUrl = new URL(\n `https://login.microsoftonline.com/${encodeURIComponent(tenantId)}/oauth2/v2.0/token`\n );\n try {\n const res = await httpRequest({\n url: reqUrl,\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body,\n timeoutMs: this.requestTimeoutMs,\n label: 'Azure token request',\n });\n const parsed = JSON.parse(res.body) as { access_token?: string; expires_in?: number };\n if (!parsed.access_token) return null;\n this.accessToken = parsed.access_token;\n this.tokenExpiry = Date.now() + (parsed.expires_in ?? 3600) * 1000 - 60_000;\n return this.accessToken;\n } catch (err) {\n internalError('AzureMonitorTransport token request failed', err);\n return null;\n }\n }\n\n private async sendEntries(entries: TransportLogEntry[]): Promise<void> {\n const token = await this.getAccessToken();\n if (!token) throw new Error('AzureMonitorTransport: no access token available');\n\n const records = entries.map((e) => this.toAzureRecord(e));\n const body = stringifyForLog(records);\n let reqUrl: URL;\n try {\n // Build from the user-configured DCE endpoint; encodeURIComponent-ing the\n // ruleId/streamName stops a hostile config from smuggling extra path\n // segments or query params into the request.\n reqUrl = new URL(\n `dataCollectionRules/${encodeURIComponent(this.ruleId)}/streams/${encodeURIComponent(this.streamName)}?api-version=2023-01-01`,\n this.endpoint.endsWith('/') ? this.endpoint : `${this.endpoint}/`\n );\n } catch (error) {\n internalError(`AzureMonitorTransport: invalid endpoint \"${this.endpoint}\"`, error);\n return;\n }\n if (reqUrl.protocol !== 'https:') {\n internalError(`AzureMonitorTransport: endpoint must use https (got ${reqUrl.protocol})`);\n return;\n }\n\n await httpRequest({\n url: reqUrl,\n headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },\n body,\n timeoutMs: this.requestTimeoutMs,\n label: 'Azure Monitor API',\n });\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"azure-monitor.transport-D5wQEH04.d.mts","names":[],"sources":["../src/transports/azure-monitor.transport.ts"],"sourcesContent":[],"mappings":";;;;UAkDiB,2BAAA;;;;;;;;;;;;;;;;;;;;;;;;;;cAwCJ,qBAAA,YAAiC;;;;;;;;;;;;;;;;sBAmBxB;eAwBP;WAKJ;;;;;;WASM"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"batch-buffer-BY-mRWIK.js","names":["status: number","body: string","http","https","opts: BatchBufferOptions<T>"],"sources":["../src/transports/batch-buffer.ts"],"sourcesContent":["/**\n * Shared batching core for the network transports (OTLP, CloudWatch, GCP, Azure).\n *\n * - one send in flight at a time; flush() and close() join it instead of\n * racing it, so close() cannot return while a request is still on the wire\n * - a failed batch goes back to the front in its original order\n * - 4xx responses other than 429 drop the batch with a warning instead of\n * retrying a request the server will never accept\n * - the buffer is capped; when full the oldest entries are dropped\n */\n\nimport * as http from 'node:http';\nimport * as https from 'node:https';\n\nimport { internalError, internalWarn } from '../utils/internal-log';\n\nexport const DEFAULT_REQUEST_TIMEOUT_MS = 10_000;\nexport const DEFAULT_MAX_BUFFER_SIZE = 10_000;\nconst WARN_INTERVAL_MS = 10_000;\nconst MAX_ERROR_BODY = 500;\nconst MAX_BACKOFF_MS = 30_000;\n\nexport class HttpError extends Error {\n constructor(\n public readonly status: number,\n public readonly body: string,\n label: string\n ) {\n const detail = body ? `: ${body.slice(0, MAX_ERROR_BODY)}` : '';\n super(`${label} returned HTTP ${status}${detail}`);\n this.name = 'HttpError';\n }\n}\n\nexport function isPermanentHttpError(err: unknown): boolean {\n return err instanceof HttpError && err.status >= 400 && err.status < 500 && err.status !== 429;\n}\n\nexport interface HttpRequestOptions {\n url: URL;\n method?: string;\n headers?: Record<string, string>;\n body?: string;\n timeoutMs: number;\n label: string;\n}\n\nexport interface HttpResult {\n status: number;\n body: string;\n}\n\n/** One request with a hard timeout. Rejects with HttpError on any non-2xx status. */\nexport function httpRequest(opts: HttpRequestOptions): Promise<HttpResult> {\n const { url, method = 'POST', headers = {}, body, timeoutMs, label } = opts;\n const transport = url.protocol === 'http:' ? http : https;\n return new Promise<HttpResult>((resolve, reject) => {\n const req = transport.request(\n {\n protocol: url.protocol,\n hostname: url.hostname,\n port: url.port || undefined,\n path: `${url.pathname}${url.search}`,\n method,\n headers:\n body === undefined ? headers : { ...headers, 'Content-Length': Buffer.byteLength(body) },\n },\n (res) => {\n let raw = '';\n res.on('data', (c: Buffer) => (raw += c.toString()));\n res.on('end', () => {\n const status = res.statusCode ?? 0;\n if (status >= 200 && status < 300) resolve({ status, body: raw });\n else reject(new HttpError(status, raw, label));\n });\n res.on('error', reject);\n }\n );\n req.setTimeout(timeoutMs, () => {\n req.destroy(new Error(`${label} timed out after ${timeoutMs}ms`));\n });\n req.on('error', reject);\n if (body !== undefined) req.write(body);\n req.end();\n });\n}\n\nexport interface BatchBufferOptions<T> {\n name: string;\n batchSize: number;\n maxBufferSize?: number;\n send: (items: T[]) => Promise<void>;\n /** Overrides the default drop-on-4xx rule. Return true to keep and retry the batch. */\n shouldRetry?: (err: unknown) => boolean;\n}\n\nexport class BatchBuffer<T> {\n private items: T[] = [];\n private inFlight: Promise<void> | undefined;\n private dropped = 0;\n private lastDropWarn = 0;\n private failures = 0;\n private retryAfter = 0;\n\n constructor(private readonly opts: BatchBufferOptions<T>) {}\n\n get length(): number {\n return this.items.length;\n }\n\n get batchSize(): number {\n return this.opts.batchSize;\n }\n\n push(item: T): void {\n this.items.push(item);\n this.enforceCap();\n }\n\n /** Threshold flush for write(): skipped while a send is running or the endpoint is backing off. */\n flushIfFull(): void {\n if (this.items.length < this.opts.batchSize || this.inFlight || Date.now() < this.retryAfter) {\n return;\n }\n this.flush().catch(() => {});\n }\n\n flush(): Promise<void> {\n if (!this.inFlight) {\n this.inFlight = this.drain().finally(() => {\n this.inFlight = undefined;\n });\n }\n return this.inFlight;\n }\n\n /** Flush up to `attempts` times, then report whatever is still undelivered. */\n async close(attempts = 3): Promise<void> {\n await this.inFlight;\n for (let i = 0; i < attempts && this.items.length > 0; i += 1) {\n await this.flush();\n }\n if (this.items.length > 0) {\n internalError(\n `${this.opts.name} closing with ${this.items.length} undelivered entr${this.items.length === 1 ? 'y' : 'ies'}`\n );\n }\n }\n\n private async drain(): Promise<void> {\n while (this.items.length > 0) {\n const batch = this.items.splice(0, this.opts.batchSize);\n try {\n await this.opts.send(batch);\n this.failures = 0;\n } catch (err) {\n const retry = this.opts.shouldRetry\n ? this.opts.shouldRetry(err)\n : !isPermanentHttpError(err);\n if (!retry) {\n internalWarn(\n `${this.opts.name}: dropping ${batch.length} entr${batch.length === 1 ? 'y' : 'ies'} the server rejected (${err instanceof Error ? err.message : String(err)})`\n );\n continue;\n }\n internalError(`${this.opts.name} flush error`, err);\n this.items.unshift(...batch);\n this.enforceCap();\n this.failures += 1;\n this.retryAfter = Date.now() + Math.min(MAX_BACKOFF_MS, 1000 * 2 ** (this.failures - 1));\n return;\n }\n }\n }\n\n private enforceCap(): void {\n const max = this.opts.maxBufferSize ?? DEFAULT_MAX_BUFFER_SIZE;\n const excess = this.items.length - max;\n if (excess <= 0) return;\n this.items.splice(0, excess);\n this.dropped += excess;\n const now = Date.now();\n if (now - this.lastDropWarn >= WARN_INTERVAL_MS) {\n internalWarn(\n `${this.opts.name}: buffer full (${max}), dropped ${this.dropped} oldest entr${this.dropped === 1 ? 'y' : 'ies'}`\n );\n this.dropped = 0;\n this.lastDropWarn = now;\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"batch-buffer-PGvSgbmd.mjs","names":["status: number","body: string","opts: BatchBufferOptions<T>"],"sources":["../src/transports/batch-buffer.ts"],"sourcesContent":["/**\n * Shared batching core for the network transports (OTLP, CloudWatch, GCP, Azure).\n *\n * - one send in flight at a time; flush() and close() join it instead of\n * racing it, so close() cannot return while a request is still on the wire\n * - a failed batch goes back to the front in its original order\n * - 4xx responses other than 429 drop the batch with a warning instead of\n * retrying a request the server will never accept\n * - the buffer is capped; when full the oldest entries are dropped\n */\n\nimport * as http from 'node:http';\nimport * as https from 'node:https';\n\nimport { internalError, internalWarn } from '../utils/internal-log';\n\nexport const DEFAULT_REQUEST_TIMEOUT_MS = 10_000;\nexport const DEFAULT_MAX_BUFFER_SIZE = 10_000;\nconst WARN_INTERVAL_MS = 10_000;\nconst MAX_ERROR_BODY = 500;\nconst MAX_BACKOFF_MS = 30_000;\n\nexport class HttpError extends Error {\n constructor(\n public readonly status: number,\n public readonly body: string,\n label: string\n ) {\n const detail = body ? `: ${body.slice(0, MAX_ERROR_BODY)}` : '';\n super(`${label} returned HTTP ${status}${detail}`);\n this.name = 'HttpError';\n }\n}\n\nexport function isPermanentHttpError(err: unknown): boolean {\n return err instanceof HttpError && err.status >= 400 && err.status < 500 && err.status !== 429;\n}\n\nexport interface HttpRequestOptions {\n url: URL;\n method?: string;\n headers?: Record<string, string>;\n body?: string;\n timeoutMs: number;\n label: string;\n}\n\nexport interface HttpResult {\n status: number;\n body: string;\n}\n\n/** One request with a hard timeout. Rejects with HttpError on any non-2xx status. */\nexport function httpRequest(opts: HttpRequestOptions): Promise<HttpResult> {\n const { url, method = 'POST', headers = {}, body, timeoutMs, label } = opts;\n const transport = url.protocol === 'http:' ? http : https;\n return new Promise<HttpResult>((resolve, reject) => {\n const req = transport.request(\n {\n protocol: url.protocol,\n hostname: url.hostname,\n port: url.port || undefined,\n path: `${url.pathname}${url.search}`,\n method,\n headers:\n body === undefined ? headers : { ...headers, 'Content-Length': Buffer.byteLength(body) },\n },\n (res) => {\n let raw = '';\n res.on('data', (c: Buffer) => (raw += c.toString()));\n res.on('end', () => {\n const status = res.statusCode ?? 0;\n if (status >= 200 && status < 300) resolve({ status, body: raw });\n else reject(new HttpError(status, raw, label));\n });\n res.on('error', reject);\n }\n );\n req.setTimeout(timeoutMs, () => {\n req.destroy(new Error(`${label} timed out after ${timeoutMs}ms`));\n });\n req.on('error', reject);\n if (body !== undefined) req.write(body);\n req.end();\n });\n}\n\nexport interface BatchBufferOptions<T> {\n name: string;\n batchSize: number;\n maxBufferSize?: number;\n send: (items: T[]) => Promise<void>;\n /** Overrides the default drop-on-4xx rule. Return true to keep and retry the batch. */\n shouldRetry?: (err: unknown) => boolean;\n}\n\nexport class BatchBuffer<T> {\n private items: T[] = [];\n private inFlight: Promise<void> | undefined;\n private dropped = 0;\n private lastDropWarn = 0;\n private failures = 0;\n private retryAfter = 0;\n\n constructor(private readonly opts: BatchBufferOptions<T>) {}\n\n get length(): number {\n return this.items.length;\n }\n\n get batchSize(): number {\n return this.opts.batchSize;\n }\n\n push(item: T): void {\n this.items.push(item);\n this.enforceCap();\n }\n\n /** Threshold flush for write(): skipped while a send is running or the endpoint is backing off. */\n flushIfFull(): void {\n if (this.items.length < this.opts.batchSize || this.inFlight || Date.now() < this.retryAfter) {\n return;\n }\n this.flush().catch(() => {});\n }\n\n flush(): Promise<void> {\n if (!this.inFlight) {\n this.inFlight = this.drain().finally(() => {\n this.inFlight = undefined;\n });\n }\n return this.inFlight;\n }\n\n /** Flush up to `attempts` times, then report whatever is still undelivered. */\n async close(attempts = 3): Promise<void> {\n await this.inFlight;\n for (let i = 0; i < attempts && this.items.length > 0; i += 1) {\n await this.flush();\n }\n if (this.items.length > 0) {\n internalError(\n `${this.opts.name} closing with ${this.items.length} undelivered entr${this.items.length === 1 ? 'y' : 'ies'}`\n );\n }\n }\n\n private async drain(): Promise<void> {\n while (this.items.length > 0) {\n const batch = this.items.splice(0, this.opts.batchSize);\n try {\n await this.opts.send(batch);\n this.failures = 0;\n } catch (err) {\n const retry = this.opts.shouldRetry\n ? this.opts.shouldRetry(err)\n : !isPermanentHttpError(err);\n if (!retry) {\n internalWarn(\n `${this.opts.name}: dropping ${batch.length} entr${batch.length === 1 ? 'y' : 'ies'} the server rejected (${err instanceof Error ? err.message : String(err)})`\n );\n continue;\n }\n internalError(`${this.opts.name} flush error`, err);\n this.items.unshift(...batch);\n this.enforceCap();\n this.failures += 1;\n this.retryAfter = Date.now() + Math.min(MAX_BACKOFF_MS, 1000 * 2 ** (this.failures - 1));\n return;\n }\n }\n }\n\n private enforceCap(): void {\n const max = this.opts.maxBufferSize ?? DEFAULT_MAX_BUFFER_SIZE;\n const excess = this.items.length - max;\n if (excess <= 0) return;\n this.items.splice(0, excess);\n this.dropped += excess;\n const now = Date.now();\n if (now - this.lastDropWarn >= WARN_INTERVAL_MS) {\n internalWarn(\n `${this.opts.name}: buffer full (${max}), dropped ${this.dropped} oldest entr${this.dropped === 1 ? 'y' : 'ies'}`\n );\n this.dropped = 0;\n this.lastDropWarn = now;\n }\n }\n}\n"],"mappings":"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"}
|
package/dist/chunk-DLSkYcPk.mjs
DELETED
package/dist/chunk-nOFOJqeH.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
//#region rolldown:runtime
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __copyProps = (to, from, except, desc) => {
|
|
9
|
-
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
10
|
-
key = keys[i];
|
|
11
|
-
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
12
|
-
get: ((k) => from[k]).bind(null, key),
|
|
13
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
19
|
-
value: mod,
|
|
20
|
-
enumerable: true
|
|
21
|
-
}) : target, mod));
|
|
22
|
-
|
|
23
|
-
//#endregion
|
|
24
|
-
|
|
25
|
-
Object.defineProperty(exports, '__toESM', {
|
|
26
|
-
enumerable: true,
|
|
27
|
-
get: function () {
|
|
28
|
-
return __toESM;
|
|
29
|
-
}
|
|
30
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cloudwatch.transport-B00st6Xv.d.ts","names":[],"sources":["../src/transports/cloudwatch.transport.ts"],"sourcesContent":[],"mappings":";;;;UA+CiB,yBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA+EJ,mBAAA,YAA+B;;;;;;;;;;;;;;;;;sBAoBtB;eAiCP;WAOJ;;;;;;WASM"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cloudwatch.transport-BO1ahxw-.js","names":["out: Record<string, Record<string, string>>","section: Record<string, string> | undefined","path","os","text: string","fs","headers: Record<string, string>","httpRequest","crypto","headers: Record<string, string>","HttpError","DEFAULT_REQUEST_TIMEOUT_MS","BatchBuffer","DEFAULT_MAX_BUFFER_SIZE","isPermanentHttpError","stringifyForLog","mergeCoreFields","metricNames: string[]","httpRequest"],"sources":["../src/transports/aws-credentials.ts","../src/transports/aws-sigv4.ts","../src/transports/cloudwatch.transport.ts"],"sourcesContent":["/**\n * AWS credential resolution without the SDK.\n *\n * Order: explicit config, environment variables, shared credentials file,\n * ECS/container credentials, EC2 instance metadata (IMDSv2).\n * Not supported: SSO, assume-role profiles, credential_process, web identity.\n */\n\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\n\nimport { internalWarn } from '../utils/internal-log';\nimport { type AwsCredentials } from './aws-sigv4';\nimport { httpRequest } from './batch-buffer';\n\nconst REFRESH_MARGIN_MS = 5 * 60 * 1000;\nconst FAILURE_BACKOFF_MS = 30 * 1000;\nconst METADATA_TIMEOUT_MS = 2000;\n\nexport interface AwsCredentialConfig {\n accessKeyId?: string | undefined;\n secretAccessKey?: string | undefined;\n sessionToken?: string | undefined;\n}\n\n/** Parse the sections of an AWS ini file into `{ section: { key: value } }`. */\nexport function parseIni(text: string): Record<string, Record<string, string>> {\n const out: Record<string, Record<string, string>> = {};\n let section: Record<string, string> | undefined;\n for (const raw of text.split(/\\r?\\n/)) {\n const line = raw.trim();\n if (!line || line.startsWith('#') || line.startsWith(';')) continue;\n const header = /^\\[(.+)\\]$/.exec(line);\n if (header) {\n section = out[header[1]!.trim()] = out[header[1]!.trim()] ?? {};\n continue;\n }\n const eq = line.indexOf('=');\n if (eq > 0 && section) section[line.slice(0, eq).trim()] = line.slice(eq + 1).trim();\n }\n return out;\n}\n\nfunction fromEnv(): AwsCredentials | undefined {\n const accessKeyId = process.env['AWS_ACCESS_KEY_ID'];\n const secretAccessKey = process.env['AWS_SECRET_ACCESS_KEY'];\n if (!accessKeyId || !secretAccessKey) return undefined;\n return { accessKeyId, secretAccessKey, sessionToken: process.env['AWS_SESSION_TOKEN'] };\n}\n\nfunction fromSharedFile(): AwsCredentials | undefined {\n const file =\n process.env['AWS_SHARED_CREDENTIALS_FILE'] ?? path.join(os.homedir(), '.aws', 'credentials');\n const profile = process.env['AWS_PROFILE'] ?? 'default';\n let text: string;\n try {\n text = fs.readFileSync(file, 'utf8');\n } catch {\n return undefined;\n }\n const section = parseIni(text)[profile];\n const accessKeyId = section?.['aws_access_key_id'];\n const secretAccessKey = section?.['aws_secret_access_key'];\n if (!accessKeyId || !secretAccessKey) return undefined;\n return { accessKeyId, secretAccessKey, sessionToken: section?.['aws_session_token'] };\n}\n\ninterface CredentialDocument {\n AccessKeyId?: string;\n SecretAccessKey?: string;\n Token?: string;\n Expiration?: string;\n}\n\nfunction fromDocument(raw: string): AwsCredentials | undefined {\n const doc = JSON.parse(raw) as CredentialDocument;\n if (!doc.AccessKeyId || !doc.SecretAccessKey) return undefined;\n const expiresAt = doc.Expiration ? Date.parse(doc.Expiration) : Number.NaN;\n return {\n accessKeyId: doc.AccessKeyId,\n secretAccessKey: doc.SecretAccessKey,\n sessionToken: doc.Token,\n expiresAt: Number.isNaN(expiresAt) ? undefined : expiresAt,\n };\n}\n\nconst CONTAINER_HOSTS = new Set([\n // eslint-disable-next-line sonarjs/no-hardcoded-ip -- fixed ECS credentials endpoint\n '169.254.170.2',\n // eslint-disable-next-line sonarjs/no-hardcoded-ip -- fixed EKS pod identity endpoint\n '169.254.170.23',\n '[fd00:ec2::23]',\n 'localhost',\n '[::1]',\n]);\n\n/** Same rule as the AWS SDKs: never send the container token to an arbitrary http host. */\nfunction isAllowedContainerHost(url: URL): boolean {\n if (url.protocol === 'https:') return true;\n if (url.protocol !== 'http:') return false;\n return CONTAINER_HOSTS.has(url.hostname) || /^127(?:\\.\\d{1,3}){3}$/.test(url.hostname);\n}\n\nasync function fromContainer(): Promise<AwsCredentials | undefined> {\n const relative = process.env['AWS_CONTAINER_CREDENTIALS_RELATIVE_URI'];\n const full = process.env['AWS_CONTAINER_CREDENTIALS_FULL_URI'];\n if (!relative && !full) return undefined;\n const url = new URL(relative ? `http://169.254.170.2${relative}` : (full as string));\n if (!relative && !isAllowedContainerHost(url)) {\n internalWarn(\n `ignoring AWS_CONTAINER_CREDENTIALS_FULL_URI: ${url.host} is not https or a loopback / ECS / EKS address`\n );\n return undefined;\n }\n const headers: Record<string, string> = {};\n const tokenFile = process.env['AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE'];\n const token = tokenFile\n ? fs.readFileSync(tokenFile, 'utf8').trim()\n : process.env['AWS_CONTAINER_AUTHORIZATION_TOKEN'];\n if (token) headers['Authorization'] = token;\n const res = await httpRequest({\n url,\n method: 'GET',\n headers,\n timeoutMs: METADATA_TIMEOUT_MS,\n label: 'AWS container credentials',\n });\n return fromDocument(res.body);\n}\n\nasync function fromInstanceMetadata(): Promise<AwsCredentials | undefined> {\n if (process.env['AWS_EC2_METADATA_DISABLED'] === 'true') return undefined;\n const base = process.env['AWS_EC2_METADATA_SERVICE_ENDPOINT'] ?? 'http://169.254.169.254';\n const get = (p: string, method: string, headers: Record<string, string>) =>\n httpRequest({\n url: new URL(p, base),\n method,\n headers,\n timeoutMs: METADATA_TIMEOUT_MS,\n label: 'EC2 instance metadata',\n });\n const session = await get('/latest/api/token', 'PUT', {\n 'X-aws-ec2-metadata-token-ttl-seconds': '21600',\n });\n const auth = { 'X-aws-ec2-metadata-token': session.body.trim() };\n const roles = await get('/latest/meta-data/iam/security-credentials/', 'GET', auth);\n const role = roles.body.split('\\n')[0]?.trim();\n if (!role) return undefined;\n const creds = await get(\n `/latest/meta-data/iam/security-credentials/${encodeURIComponent(role)}`,\n 'GET',\n auth\n );\n return fromDocument(creds.body);\n}\n\nexport class AwsCredentialProvider {\n private cached: AwsCredentials | undefined;\n private failedAt = 0;\n private readonly explicit: AwsCredentials | undefined;\n\n constructor(config: AwsCredentialConfig) {\n if (config.accessKeyId && config.secretAccessKey) {\n this.explicit = {\n accessKeyId: config.accessKeyId,\n secretAccessKey: config.secretAccessKey,\n sessionToken: config.sessionToken,\n };\n }\n }\n\n /** Throws when no source yields credentials, so the caller keeps its buffer. */\n async get(): Promise<AwsCredentials> {\n if (this.explicit) return this.explicit;\n const env = fromEnv();\n if (env) return env;\n if (this.cached && !this.isExpiring(this.cached)) return this.cached;\n if (Date.now() - this.failedAt < FAILURE_BACKOFF_MS) {\n throw new Error('no AWS credentials found (retrying shortly)');\n }\n\n let found = fromSharedFile();\n for (const source of [fromContainer, fromInstanceMetadata]) {\n if (found) break;\n try {\n found = await source();\n } catch {\n /* source not available here; try the next */\n }\n }\n if (!found) {\n this.failedAt = Date.now();\n throw new Error(\n 'no AWS credentials found: set AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY, a shared credentials file, container credentials, or run on EC2 with an instance role'\n );\n }\n this.cached = found;\n return found;\n }\n\n invalidate(): void {\n this.cached = undefined;\n this.failedAt = 0;\n }\n\n private isExpiring(c: AwsCredentials): boolean {\n return c.expiresAt !== undefined && c.expiresAt - Date.now() < REFRESH_MARGIN_MS;\n }\n}\n","/**\n * AWS Signature Version 4 request signing, dependency-free.\n */\n\nimport * as crypto from 'node:crypto';\n\nexport interface AwsCredentials {\n accessKeyId: string;\n secretAccessKey: string;\n sessionToken?: string | undefined;\n /** Epoch ms after which the credentials are no longer valid. */\n expiresAt?: number | undefined;\n}\n\nexport interface SignV4Options {\n method: string;\n path: string;\n query?: string;\n /** Must include `host`. Names are lowercased before signing. */\n headers: Record<string, string>;\n body: string;\n region: string;\n service: string;\n credentials: AwsCredentials;\n date?: Date;\n}\n\nconst sha256Hex = (data: string): string => crypto.createHash('sha256').update(data).digest('hex');\n\nconst hmac = (key: Buffer | string, msg: string): Buffer =>\n crypto.createHmac('sha256', key).update(msg).digest();\n\n/** Returns the request headers (lowercase names) with `x-amz-date` and `authorization` added. */\nexport function signV4(opts: SignV4Options): Record<string, string> {\n const {\n method,\n path,\n query = '',\n body,\n region,\n service,\n credentials,\n headers: input,\n date,\n } = opts;\n const amzDate = (date ?? new Date()).toISOString().replace(/[:-]|\\.\\d{3}/g, '');\n const dateStamp = amzDate.slice(0, 8);\n\n const headers: Record<string, string> = {};\n for (const [k, v] of Object.entries(input)) headers[k.toLowerCase()] = v;\n headers['x-amz-date'] = amzDate;\n if (credentials.sessionToken) headers['x-amz-security-token'] = credentials.sessionToken;\n\n const names = Object.keys(headers).sort();\n const canonicalHeaders = names\n .map((n) => `${n}:${headers[n]!.trim().replace(/\\s+/g, ' ')}\\n`)\n .join('');\n const signedHeaders = names.join(';');\n\n const canonicalRequest = [\n method,\n path,\n query,\n canonicalHeaders,\n signedHeaders,\n sha256Hex(body),\n ].join('\\n');\n const scope = `${dateStamp}/${region}/${service}/aws4_request`;\n const stringToSign = ['AWS4-HMAC-SHA256', amzDate, scope, sha256Hex(canonicalRequest)].join('\\n');\n\n const signingKey = hmac(\n hmac(hmac(hmac(`AWS4${credentials.secretAccessKey}`, dateStamp), region), service),\n 'aws4_request'\n );\n const signature = crypto.createHmac('sha256', signingKey).update(stringToSign).digest('hex');\n\n headers['authorization'] =\n `AWS4-HMAC-SHA256 Credential=${credentials.accessKeyId}/${scope}, ` +\n `SignedHeaders=${signedHeaders}, Signature=${signature}`;\n return headers;\n}\n","/**\n * logixia — AWS CloudWatch Logs transport\n *\n * Sends log entries to AWS CloudWatch Logs via the PutLogEvents API.\n * Supports EMF (Embedded Metric Format) for automatic metric extraction.\n *\n * Auth, in order: explicit config, environment variables, the shared\n * credentials file (AWS_PROFILE, AWS_SHARED_CREDENTIALS_FILE), ECS container\n * credentials, then EC2 instance metadata (IMDSv2). SSO, assume-role profiles\n * and credential_process are not supported. No SDK dependency — raw HTTPS with\n * AWS Signature Version 4.\n *\n * The log group and stream are created on first use if they do not exist.\n *\n * @example\n * ```ts\n * import { CloudWatchTransport } from 'logixia';\n *\n * const logger = createLogger({\n * transports: {\n * cloudwatch: new CloudWatchTransport({\n * region: 'us-east-1',\n * logGroupName: '/myapp/production',\n * logStreamName: `api-${process.env.HOSTNAME}`,\n * batchSize: 100,\n * flushIntervalMs: 5000,\n * }),\n * },\n * });\n * ```\n */\n\nimport type { IAsyncTransport, TransportLogEntry } from '../types/transport.types';\nimport { internalWarn } from '../utils/internal-log';\nimport { stringifyForLog } from '../utils/safe-stringify';\nimport { AwsCredentialProvider } from './aws-credentials';\nimport { signV4 } from './aws-sigv4';\nimport {\n BatchBuffer,\n DEFAULT_MAX_BUFFER_SIZE,\n DEFAULT_REQUEST_TIMEOUT_MS,\n HttpError,\n httpRequest,\n isPermanentHttpError,\n} from './batch-buffer';\nimport { mergeCoreFields } from './entry-fields';\n\nexport interface CloudWatchTransportConfig {\n /** AWS region, e.g. `'us-east-1'`. Falls back to `AWS_REGION` env var. */\n region?: string;\n /** CloudWatch Logs group name. Created automatically if it does not exist. */\n logGroupName: string;\n /** CloudWatch Logs stream name. Defaults to hostname + process PID. */\n logStreamName?: string;\n /** Override the Logs endpoint, e.g. for LocalStack. Default: `https://logs.<region>.amazonaws.com`. */\n endpoint?: string;\n /** AWS access key ID. Falls back to the credential chain described above. */\n accessKeyId?: string;\n /** AWS secret access key. Used together with `accessKeyId`. */\n secretAccessKey?: string;\n /** AWS session token for temporary credentials. Used together with `accessKeyId`. */\n sessionToken?: string;\n /**\n * Number of log events to batch before flushing.\n * CloudWatch allows max 10,000 events per PutLogEvents call; larger values are capped.\n * @default 100\n */\n batchSize?: number;\n /**\n * Max ms between flushes even if batchSize is not reached.\n * @default 5000\n */\n flushIntervalMs?: number;\n /**\n * Enable EMF (Embedded Metric Format) — wraps log entries as CloudWatch\n * metric namespaces so numeric fields become CloudWatch Metrics automatically.\n * @default false\n */\n emf?: boolean;\n /** CloudWatch Metrics namespace used by EMF. @default 'Logixia' */\n emfNamespace?: string;\n /**\n * Payload fields published as EMF metrics. When set, only these numeric\n * fields become metrics; when unset every numeric payload field does (up to\n * the EMF limit of 100 per entry).\n */\n emfMetrics?: string[];\n /** Abort a request that has not finished after this many ms. @default 10000 */\n requestTimeoutMs?: number;\n /** Max buffered events; the oldest are dropped past this. @default 10000 */\n maxBufferSize?: number;\n /** Minimum log level to forward. */\n level?: string;\n}\n\nconst MAX_EVENTS_PER_PUT = 10_000;\nconst EMF_MAX_METRICS = 100;\n\n/** Error types worth retrying even though CloudWatch reports them as HTTP 400. */\nconst RETRYABLE_TYPES = new Set([\n 'ThrottlingException',\n 'ThrottledException',\n 'LimitExceededException',\n 'ServiceUnavailableException',\n 'ExpiredTokenException',\n 'ResourceNotFoundException',\n]);\n\nfunction awsErrorType(err: unknown): string | undefined {\n if (!(err instanceof HttpError)) return undefined;\n try {\n const type = (JSON.parse(err.body) as { __type?: string }).__type;\n return type?.split('#').pop();\n } catch {\n return undefined;\n }\n}\n\ninterface CwLogEvent {\n timestamp: number;\n message: string;\n}\n\n/**\n * AWS CloudWatch Logs transport with EMF support and batched PutLogEvents calls.\n */\nexport class CloudWatchTransport implements IAsyncTransport {\n public readonly name = 'cloudwatch';\n public readonly batchSize: number;\n public readonly flushInterval: number;\n public readonly level: string | undefined;\n\n private readonly buffer: BatchBuffer<CwLogEvent>;\n private readonly requestTimeoutMs: number;\n private flushTimer: NodeJS.Timeout | null = null;\n private readonly credentials: AwsCredentialProvider;\n private readonly endpoint: URL;\n private streamReady = false;\n\n private readonly region: string;\n private readonly logGroupName: string;\n private readonly logStreamName: string;\n private readonly emf: boolean;\n private readonly emfNamespace: string;\n private readonly emfMetrics: ReadonlySet<string> | undefined;\n\n constructor(config: CloudWatchTransportConfig) {\n this.region =\n config.region ??\n process.env['AWS_REGION'] ??\n process.env['AWS_DEFAULT_REGION'] ??\n 'us-east-1';\n this.logGroupName = config.logGroupName;\n this.logStreamName =\n config.logStreamName ?? `${process.env['HOSTNAME'] ?? 'node'}-${process.pid}`;\n this.credentials = new AwsCredentialProvider(config);\n this.endpoint = new URL(config.endpoint ?? `https://logs.${this.region}.amazonaws.com`);\n this.batchSize = Math.min(config.batchSize ?? 100, MAX_EVENTS_PER_PUT);\n this.emfNamespace = config.emfNamespace ?? 'Logixia';\n this.flushInterval = config.flushIntervalMs ?? 5000;\n this.emf = config.emf ?? false;\n this.emfMetrics = config.emfMetrics ? new Set(config.emfMetrics) : undefined;\n this.level = config.level;\n this.requestTimeoutMs = config.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;\n this.buffer = new BatchBuffer<CwLogEvent>({\n name: 'CloudWatchTransport',\n batchSize: this.batchSize,\n maxBufferSize: config.maxBufferSize ?? DEFAULT_MAX_BUFFER_SIZE,\n send: (events) => this.putLogEvents(events),\n shouldRetry: (err) =>\n !isPermanentHttpError(err) || RETRYABLE_TYPES.has(awsErrorType(err) ?? ''),\n });\n\n this.flushTimer = setInterval(() => {\n this.flush().catch(() => {});\n }, this.flushInterval);\n if (this.flushTimer.unref) this.flushTimer.unref();\n }\n\n write(entry: TransportLogEntry): void {\n const timestamp = entry.timestamp ? new Date(entry.timestamp).getTime() : Date.now();\n const message = this.emf ? this.toEmf(entry) : stringifyForLog(entry);\n this.buffer.push({ timestamp, message });\n this.buffer.flushIfFull();\n }\n\n flush(): Promise<void> {\n return this.buffer.flush();\n }\n\n /**\n * Flush remaining events and stop the interval timer on shutdown. Without this\n * the manager's close() skips the transport (close was undefined) and any\n * buffered events were lost on deploy. Waits for any in-flight send first.\n */\n async close(): Promise<void> {\n if (this.flushTimer) {\n clearInterval(this.flushTimer);\n this.flushTimer = null;\n }\n await this.buffer.close();\n }\n\n private toEmf(entry: TransportLogEntry): string {\n const { level, message, data: payload, timestamp } = entry;\n const fields = mergeCoreFields({ _aws: undefined, level, message }, payload);\n const metricNames: string[] = [];\n for (const [k, v] of Object.entries(fields)) {\n if (k === '_aws' || k === 'level' || k === 'message' || typeof v !== 'number') continue;\n if (this.emfMetrics && !this.emfMetrics.has(k)) continue;\n if (metricNames.length < EMF_MAX_METRICS) metricNames.push(k);\n }\n fields['_aws'] = {\n Timestamp: timestamp ? new Date(timestamp).getTime() : Date.now(),\n CloudWatchMetrics:\n metricNames.length > 0\n ? [\n {\n Namespace: this.emfNamespace,\n Dimensions: [['level']],\n Metrics: metricNames.map((n) => ({ Name: n, Unit: 'None' })),\n },\n ]\n : [],\n };\n return stringifyForLog(fields);\n }\n\n private async putLogEvents(events: CwLogEvent[]): Promise<void> {\n await this.ensureStream();\n const logEvents = [...events].sort((a, b) => a.timestamp - b.timestamp);\n try {\n await this.call('PutLogEvents', {\n logGroupName: this.logGroupName,\n logStreamName: this.logStreamName,\n logEvents,\n });\n } catch (err) {\n const type = awsErrorType(err);\n if (type === 'DataAlreadyAcceptedException') return;\n if (type === 'ResourceNotFoundException') this.streamReady = false;\n if (type === 'ExpiredTokenException') this.credentials.invalidate();\n throw err;\n }\n }\n\n private async ensureStream(): Promise<void> {\n if (this.streamReady) return;\n try {\n await this.call('CreateLogGroup', { logGroupName: this.logGroupName });\n } catch (err) {\n if (awsErrorType(err) === 'ExpiredTokenException') this.credentials.invalidate();\n if (!(err instanceof HttpError)) throw err;\n if (awsErrorType(err) !== 'ResourceAlreadyExistsException') {\n internalWarn(`CloudWatchTransport: CreateLogGroup failed, continuing (${err.message})`);\n }\n }\n try {\n await this.call('CreateLogStream', {\n logGroupName: this.logGroupName,\n logStreamName: this.logStreamName,\n });\n } catch (err) {\n if (awsErrorType(err) !== 'ResourceAlreadyExistsException') throw err;\n }\n this.streamReady = true;\n }\n\n private async call(action: string, payload: Record<string, unknown>): Promise<void> {\n const credentials = await this.credentials.get();\n const body = stringifyForLog(payload);\n const { host } = this.endpoint;\n const headers = signV4({\n method: 'POST',\n path: '/',\n headers: {\n host,\n 'content-type': 'application/x-amz-json-1.1',\n 'x-amz-target': `Logs_20140328.${action}`,\n },\n body,\n region: this.region,\n service: 'logs',\n credentials,\n });\n await httpRequest({\n url: this.endpoint,\n headers,\n body,\n timeoutMs: this.requestTimeoutMs,\n label: `CloudWatch ${action}`,\n });\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cloudwatch.transport-Blc7Gtxt.d.mts","names":[],"sources":["../src/transports/cloudwatch.transport.ts"],"sourcesContent":[],"mappings":";;;;UA+CiB,yBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA+EJ,mBAAA,YAA+B;;;;;;;;;;;;;;;;;sBAoBtB;eAiCP;WAOJ;;;;;;WASM"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cloudwatch.transport-DZ6ies7g.mjs","names":["out: Record<string, Record<string, string>>","section: Record<string, string> | undefined","path","text: string","headers: Record<string, string>","headers: Record<string, string>","path","metricNames: string[]"],"sources":["../src/transports/aws-credentials.ts","../src/transports/aws-sigv4.ts","../src/transports/cloudwatch.transport.ts"],"sourcesContent":["/**\n * AWS credential resolution without the SDK.\n *\n * Order: explicit config, environment variables, shared credentials file,\n * ECS/container credentials, EC2 instance metadata (IMDSv2).\n * Not supported: SSO, assume-role profiles, credential_process, web identity.\n */\n\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\n\nimport { internalWarn } from '../utils/internal-log';\nimport { type AwsCredentials } from './aws-sigv4';\nimport { httpRequest } from './batch-buffer';\n\nconst REFRESH_MARGIN_MS = 5 * 60 * 1000;\nconst FAILURE_BACKOFF_MS = 30 * 1000;\nconst METADATA_TIMEOUT_MS = 2000;\n\nexport interface AwsCredentialConfig {\n accessKeyId?: string | undefined;\n secretAccessKey?: string | undefined;\n sessionToken?: string | undefined;\n}\n\n/** Parse the sections of an AWS ini file into `{ section: { key: value } }`. */\nexport function parseIni(text: string): Record<string, Record<string, string>> {\n const out: Record<string, Record<string, string>> = {};\n let section: Record<string, string> | undefined;\n for (const raw of text.split(/\\r?\\n/)) {\n const line = raw.trim();\n if (!line || line.startsWith('#') || line.startsWith(';')) continue;\n const header = /^\\[(.+)\\]$/.exec(line);\n if (header) {\n section = out[header[1]!.trim()] = out[header[1]!.trim()] ?? {};\n continue;\n }\n const eq = line.indexOf('=');\n if (eq > 0 && section) section[line.slice(0, eq).trim()] = line.slice(eq + 1).trim();\n }\n return out;\n}\n\nfunction fromEnv(): AwsCredentials | undefined {\n const accessKeyId = process.env['AWS_ACCESS_KEY_ID'];\n const secretAccessKey = process.env['AWS_SECRET_ACCESS_KEY'];\n if (!accessKeyId || !secretAccessKey) return undefined;\n return { accessKeyId, secretAccessKey, sessionToken: process.env['AWS_SESSION_TOKEN'] };\n}\n\nfunction fromSharedFile(): AwsCredentials | undefined {\n const file =\n process.env['AWS_SHARED_CREDENTIALS_FILE'] ?? path.join(os.homedir(), '.aws', 'credentials');\n const profile = process.env['AWS_PROFILE'] ?? 'default';\n let text: string;\n try {\n text = fs.readFileSync(file, 'utf8');\n } catch {\n return undefined;\n }\n const section = parseIni(text)[profile];\n const accessKeyId = section?.['aws_access_key_id'];\n const secretAccessKey = section?.['aws_secret_access_key'];\n if (!accessKeyId || !secretAccessKey) return undefined;\n return { accessKeyId, secretAccessKey, sessionToken: section?.['aws_session_token'] };\n}\n\ninterface CredentialDocument {\n AccessKeyId?: string;\n SecretAccessKey?: string;\n Token?: string;\n Expiration?: string;\n}\n\nfunction fromDocument(raw: string): AwsCredentials | undefined {\n const doc = JSON.parse(raw) as CredentialDocument;\n if (!doc.AccessKeyId || !doc.SecretAccessKey) return undefined;\n const expiresAt = doc.Expiration ? Date.parse(doc.Expiration) : Number.NaN;\n return {\n accessKeyId: doc.AccessKeyId,\n secretAccessKey: doc.SecretAccessKey,\n sessionToken: doc.Token,\n expiresAt: Number.isNaN(expiresAt) ? undefined : expiresAt,\n };\n}\n\nconst CONTAINER_HOSTS = new Set([\n // eslint-disable-next-line sonarjs/no-hardcoded-ip -- fixed ECS credentials endpoint\n '169.254.170.2',\n // eslint-disable-next-line sonarjs/no-hardcoded-ip -- fixed EKS pod identity endpoint\n '169.254.170.23',\n '[fd00:ec2::23]',\n 'localhost',\n '[::1]',\n]);\n\n/** Same rule as the AWS SDKs: never send the container token to an arbitrary http host. */\nfunction isAllowedContainerHost(url: URL): boolean {\n if (url.protocol === 'https:') return true;\n if (url.protocol !== 'http:') return false;\n return CONTAINER_HOSTS.has(url.hostname) || /^127(?:\\.\\d{1,3}){3}$/.test(url.hostname);\n}\n\nasync function fromContainer(): Promise<AwsCredentials | undefined> {\n const relative = process.env['AWS_CONTAINER_CREDENTIALS_RELATIVE_URI'];\n const full = process.env['AWS_CONTAINER_CREDENTIALS_FULL_URI'];\n if (!relative && !full) return undefined;\n const url = new URL(relative ? `http://169.254.170.2${relative}` : (full as string));\n if (!relative && !isAllowedContainerHost(url)) {\n internalWarn(\n `ignoring AWS_CONTAINER_CREDENTIALS_FULL_URI: ${url.host} is not https or a loopback / ECS / EKS address`\n );\n return undefined;\n }\n const headers: Record<string, string> = {};\n const tokenFile = process.env['AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE'];\n const token = tokenFile\n ? fs.readFileSync(tokenFile, 'utf8').trim()\n : process.env['AWS_CONTAINER_AUTHORIZATION_TOKEN'];\n if (token) headers['Authorization'] = token;\n const res = await httpRequest({\n url,\n method: 'GET',\n headers,\n timeoutMs: METADATA_TIMEOUT_MS,\n label: 'AWS container credentials',\n });\n return fromDocument(res.body);\n}\n\nasync function fromInstanceMetadata(): Promise<AwsCredentials | undefined> {\n if (process.env['AWS_EC2_METADATA_DISABLED'] === 'true') return undefined;\n const base = process.env['AWS_EC2_METADATA_SERVICE_ENDPOINT'] ?? 'http://169.254.169.254';\n const get = (p: string, method: string, headers: Record<string, string>) =>\n httpRequest({\n url: new URL(p, base),\n method,\n headers,\n timeoutMs: METADATA_TIMEOUT_MS,\n label: 'EC2 instance metadata',\n });\n const session = await get('/latest/api/token', 'PUT', {\n 'X-aws-ec2-metadata-token-ttl-seconds': '21600',\n });\n const auth = { 'X-aws-ec2-metadata-token': session.body.trim() };\n const roles = await get('/latest/meta-data/iam/security-credentials/', 'GET', auth);\n const role = roles.body.split('\\n')[0]?.trim();\n if (!role) return undefined;\n const creds = await get(\n `/latest/meta-data/iam/security-credentials/${encodeURIComponent(role)}`,\n 'GET',\n auth\n );\n return fromDocument(creds.body);\n}\n\nexport class AwsCredentialProvider {\n private cached: AwsCredentials | undefined;\n private failedAt = 0;\n private readonly explicit: AwsCredentials | undefined;\n\n constructor(config: AwsCredentialConfig) {\n if (config.accessKeyId && config.secretAccessKey) {\n this.explicit = {\n accessKeyId: config.accessKeyId,\n secretAccessKey: config.secretAccessKey,\n sessionToken: config.sessionToken,\n };\n }\n }\n\n /** Throws when no source yields credentials, so the caller keeps its buffer. */\n async get(): Promise<AwsCredentials> {\n if (this.explicit) return this.explicit;\n const env = fromEnv();\n if (env) return env;\n if (this.cached && !this.isExpiring(this.cached)) return this.cached;\n if (Date.now() - this.failedAt < FAILURE_BACKOFF_MS) {\n throw new Error('no AWS credentials found (retrying shortly)');\n }\n\n let found = fromSharedFile();\n for (const source of [fromContainer, fromInstanceMetadata]) {\n if (found) break;\n try {\n found = await source();\n } catch {\n /* source not available here; try the next */\n }\n }\n if (!found) {\n this.failedAt = Date.now();\n throw new Error(\n 'no AWS credentials found: set AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY, a shared credentials file, container credentials, or run on EC2 with an instance role'\n );\n }\n this.cached = found;\n return found;\n }\n\n invalidate(): void {\n this.cached = undefined;\n this.failedAt = 0;\n }\n\n private isExpiring(c: AwsCredentials): boolean {\n return c.expiresAt !== undefined && c.expiresAt - Date.now() < REFRESH_MARGIN_MS;\n }\n}\n","/**\n * AWS Signature Version 4 request signing, dependency-free.\n */\n\nimport * as crypto from 'node:crypto';\n\nexport interface AwsCredentials {\n accessKeyId: string;\n secretAccessKey: string;\n sessionToken?: string | undefined;\n /** Epoch ms after which the credentials are no longer valid. */\n expiresAt?: number | undefined;\n}\n\nexport interface SignV4Options {\n method: string;\n path: string;\n query?: string;\n /** Must include `host`. Names are lowercased before signing. */\n headers: Record<string, string>;\n body: string;\n region: string;\n service: string;\n credentials: AwsCredentials;\n date?: Date;\n}\n\nconst sha256Hex = (data: string): string => crypto.createHash('sha256').update(data).digest('hex');\n\nconst hmac = (key: Buffer | string, msg: string): Buffer =>\n crypto.createHmac('sha256', key).update(msg).digest();\n\n/** Returns the request headers (lowercase names) with `x-amz-date` and `authorization` added. */\nexport function signV4(opts: SignV4Options): Record<string, string> {\n const {\n method,\n path,\n query = '',\n body,\n region,\n service,\n credentials,\n headers: input,\n date,\n } = opts;\n const amzDate = (date ?? new Date()).toISOString().replace(/[:-]|\\.\\d{3}/g, '');\n const dateStamp = amzDate.slice(0, 8);\n\n const headers: Record<string, string> = {};\n for (const [k, v] of Object.entries(input)) headers[k.toLowerCase()] = v;\n headers['x-amz-date'] = amzDate;\n if (credentials.sessionToken) headers['x-amz-security-token'] = credentials.sessionToken;\n\n const names = Object.keys(headers).sort();\n const canonicalHeaders = names\n .map((n) => `${n}:${headers[n]!.trim().replace(/\\s+/g, ' ')}\\n`)\n .join('');\n const signedHeaders = names.join(';');\n\n const canonicalRequest = [\n method,\n path,\n query,\n canonicalHeaders,\n signedHeaders,\n sha256Hex(body),\n ].join('\\n');\n const scope = `${dateStamp}/${region}/${service}/aws4_request`;\n const stringToSign = ['AWS4-HMAC-SHA256', amzDate, scope, sha256Hex(canonicalRequest)].join('\\n');\n\n const signingKey = hmac(\n hmac(hmac(hmac(`AWS4${credentials.secretAccessKey}`, dateStamp), region), service),\n 'aws4_request'\n );\n const signature = crypto.createHmac('sha256', signingKey).update(stringToSign).digest('hex');\n\n headers['authorization'] =\n `AWS4-HMAC-SHA256 Credential=${credentials.accessKeyId}/${scope}, ` +\n `SignedHeaders=${signedHeaders}, Signature=${signature}`;\n return headers;\n}\n","/**\n * logixia — AWS CloudWatch Logs transport\n *\n * Sends log entries to AWS CloudWatch Logs via the PutLogEvents API.\n * Supports EMF (Embedded Metric Format) for automatic metric extraction.\n *\n * Auth, in order: explicit config, environment variables, the shared\n * credentials file (AWS_PROFILE, AWS_SHARED_CREDENTIALS_FILE), ECS container\n * credentials, then EC2 instance metadata (IMDSv2). SSO, assume-role profiles\n * and credential_process are not supported. No SDK dependency — raw HTTPS with\n * AWS Signature Version 4.\n *\n * The log group and stream are created on first use if they do not exist.\n *\n * @example\n * ```ts\n * import { CloudWatchTransport } from 'logixia';\n *\n * const logger = createLogger({\n * transports: {\n * cloudwatch: new CloudWatchTransport({\n * region: 'us-east-1',\n * logGroupName: '/myapp/production',\n * logStreamName: `api-${process.env.HOSTNAME}`,\n * batchSize: 100,\n * flushIntervalMs: 5000,\n * }),\n * },\n * });\n * ```\n */\n\nimport type { IAsyncTransport, TransportLogEntry } from '../types/transport.types';\nimport { internalWarn } from '../utils/internal-log';\nimport { stringifyForLog } from '../utils/safe-stringify';\nimport { AwsCredentialProvider } from './aws-credentials';\nimport { signV4 } from './aws-sigv4';\nimport {\n BatchBuffer,\n DEFAULT_MAX_BUFFER_SIZE,\n DEFAULT_REQUEST_TIMEOUT_MS,\n HttpError,\n httpRequest,\n isPermanentHttpError,\n} from './batch-buffer';\nimport { mergeCoreFields } from './entry-fields';\n\nexport interface CloudWatchTransportConfig {\n /** AWS region, e.g. `'us-east-1'`. Falls back to `AWS_REGION` env var. */\n region?: string;\n /** CloudWatch Logs group name. Created automatically if it does not exist. */\n logGroupName: string;\n /** CloudWatch Logs stream name. Defaults to hostname + process PID. */\n logStreamName?: string;\n /** Override the Logs endpoint, e.g. for LocalStack. Default: `https://logs.<region>.amazonaws.com`. */\n endpoint?: string;\n /** AWS access key ID. Falls back to the credential chain described above. */\n accessKeyId?: string;\n /** AWS secret access key. Used together with `accessKeyId`. */\n secretAccessKey?: string;\n /** AWS session token for temporary credentials. Used together with `accessKeyId`. */\n sessionToken?: string;\n /**\n * Number of log events to batch before flushing.\n * CloudWatch allows max 10,000 events per PutLogEvents call; larger values are capped.\n * @default 100\n */\n batchSize?: number;\n /**\n * Max ms between flushes even if batchSize is not reached.\n * @default 5000\n */\n flushIntervalMs?: number;\n /**\n * Enable EMF (Embedded Metric Format) — wraps log entries as CloudWatch\n * metric namespaces so numeric fields become CloudWatch Metrics automatically.\n * @default false\n */\n emf?: boolean;\n /** CloudWatch Metrics namespace used by EMF. @default 'Logixia' */\n emfNamespace?: string;\n /**\n * Payload fields published as EMF metrics. When set, only these numeric\n * fields become metrics; when unset every numeric payload field does (up to\n * the EMF limit of 100 per entry).\n */\n emfMetrics?: string[];\n /** Abort a request that has not finished after this many ms. @default 10000 */\n requestTimeoutMs?: number;\n /** Max buffered events; the oldest are dropped past this. @default 10000 */\n maxBufferSize?: number;\n /** Minimum log level to forward. */\n level?: string;\n}\n\nconst MAX_EVENTS_PER_PUT = 10_000;\nconst EMF_MAX_METRICS = 100;\n\n/** Error types worth retrying even though CloudWatch reports them as HTTP 400. */\nconst RETRYABLE_TYPES = new Set([\n 'ThrottlingException',\n 'ThrottledException',\n 'LimitExceededException',\n 'ServiceUnavailableException',\n 'ExpiredTokenException',\n 'ResourceNotFoundException',\n]);\n\nfunction awsErrorType(err: unknown): string | undefined {\n if (!(err instanceof HttpError)) return undefined;\n try {\n const type = (JSON.parse(err.body) as { __type?: string }).__type;\n return type?.split('#').pop();\n } catch {\n return undefined;\n }\n}\n\ninterface CwLogEvent {\n timestamp: number;\n message: string;\n}\n\n/**\n * AWS CloudWatch Logs transport with EMF support and batched PutLogEvents calls.\n */\nexport class CloudWatchTransport implements IAsyncTransport {\n public readonly name = 'cloudwatch';\n public readonly batchSize: number;\n public readonly flushInterval: number;\n public readonly level: string | undefined;\n\n private readonly buffer: BatchBuffer<CwLogEvent>;\n private readonly requestTimeoutMs: number;\n private flushTimer: NodeJS.Timeout | null = null;\n private readonly credentials: AwsCredentialProvider;\n private readonly endpoint: URL;\n private streamReady = false;\n\n private readonly region: string;\n private readonly logGroupName: string;\n private readonly logStreamName: string;\n private readonly emf: boolean;\n private readonly emfNamespace: string;\n private readonly emfMetrics: ReadonlySet<string> | undefined;\n\n constructor(config: CloudWatchTransportConfig) {\n this.region =\n config.region ??\n process.env['AWS_REGION'] ??\n process.env['AWS_DEFAULT_REGION'] ??\n 'us-east-1';\n this.logGroupName = config.logGroupName;\n this.logStreamName =\n config.logStreamName ?? `${process.env['HOSTNAME'] ?? 'node'}-${process.pid}`;\n this.credentials = new AwsCredentialProvider(config);\n this.endpoint = new URL(config.endpoint ?? `https://logs.${this.region}.amazonaws.com`);\n this.batchSize = Math.min(config.batchSize ?? 100, MAX_EVENTS_PER_PUT);\n this.emfNamespace = config.emfNamespace ?? 'Logixia';\n this.flushInterval = config.flushIntervalMs ?? 5000;\n this.emf = config.emf ?? false;\n this.emfMetrics = config.emfMetrics ? new Set(config.emfMetrics) : undefined;\n this.level = config.level;\n this.requestTimeoutMs = config.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;\n this.buffer = new BatchBuffer<CwLogEvent>({\n name: 'CloudWatchTransport',\n batchSize: this.batchSize,\n maxBufferSize: config.maxBufferSize ?? DEFAULT_MAX_BUFFER_SIZE,\n send: (events) => this.putLogEvents(events),\n shouldRetry: (err) =>\n !isPermanentHttpError(err) || RETRYABLE_TYPES.has(awsErrorType(err) ?? ''),\n });\n\n this.flushTimer = setInterval(() => {\n this.flush().catch(() => {});\n }, this.flushInterval);\n if (this.flushTimer.unref) this.flushTimer.unref();\n }\n\n write(entry: TransportLogEntry): void {\n const timestamp = entry.timestamp ? new Date(entry.timestamp).getTime() : Date.now();\n const message = this.emf ? this.toEmf(entry) : stringifyForLog(entry);\n this.buffer.push({ timestamp, message });\n this.buffer.flushIfFull();\n }\n\n flush(): Promise<void> {\n return this.buffer.flush();\n }\n\n /**\n * Flush remaining events and stop the interval timer on shutdown. Without this\n * the manager's close() skips the transport (close was undefined) and any\n * buffered events were lost on deploy. Waits for any in-flight send first.\n */\n async close(): Promise<void> {\n if (this.flushTimer) {\n clearInterval(this.flushTimer);\n this.flushTimer = null;\n }\n await this.buffer.close();\n }\n\n private toEmf(entry: TransportLogEntry): string {\n const { level, message, data: payload, timestamp } = entry;\n const fields = mergeCoreFields({ _aws: undefined, level, message }, payload);\n const metricNames: string[] = [];\n for (const [k, v] of Object.entries(fields)) {\n if (k === '_aws' || k === 'level' || k === 'message' || typeof v !== 'number') continue;\n if (this.emfMetrics && !this.emfMetrics.has(k)) continue;\n if (metricNames.length < EMF_MAX_METRICS) metricNames.push(k);\n }\n fields['_aws'] = {\n Timestamp: timestamp ? new Date(timestamp).getTime() : Date.now(),\n CloudWatchMetrics:\n metricNames.length > 0\n ? [\n {\n Namespace: this.emfNamespace,\n Dimensions: [['level']],\n Metrics: metricNames.map((n) => ({ Name: n, Unit: 'None' })),\n },\n ]\n : [],\n };\n return stringifyForLog(fields);\n }\n\n private async putLogEvents(events: CwLogEvent[]): Promise<void> {\n await this.ensureStream();\n const logEvents = [...events].sort((a, b) => a.timestamp - b.timestamp);\n try {\n await this.call('PutLogEvents', {\n logGroupName: this.logGroupName,\n logStreamName: this.logStreamName,\n logEvents,\n });\n } catch (err) {\n const type = awsErrorType(err);\n if (type === 'DataAlreadyAcceptedException') return;\n if (type === 'ResourceNotFoundException') this.streamReady = false;\n if (type === 'ExpiredTokenException') this.credentials.invalidate();\n throw err;\n }\n }\n\n private async ensureStream(): Promise<void> {\n if (this.streamReady) return;\n try {\n await this.call('CreateLogGroup', { logGroupName: this.logGroupName });\n } catch (err) {\n if (awsErrorType(err) === 'ExpiredTokenException') this.credentials.invalidate();\n if (!(err instanceof HttpError)) throw err;\n if (awsErrorType(err) !== 'ResourceAlreadyExistsException') {\n internalWarn(`CloudWatchTransport: CreateLogGroup failed, continuing (${err.message})`);\n }\n }\n try {\n await this.call('CreateLogStream', {\n logGroupName: this.logGroupName,\n logStreamName: this.logStreamName,\n });\n } catch (err) {\n if (awsErrorType(err) !== 'ResourceAlreadyExistsException') throw err;\n }\n this.streamReady = true;\n }\n\n private async call(action: string, payload: Record<string, unknown>): Promise<void> {\n const credentials = await this.credentials.get();\n const body = stringifyForLog(payload);\n const { host } = this.endpoint;\n const headers = signV4({\n method: 'POST',\n path: '/',\n headers: {\n host,\n 'content-type': 'application/x-amz-json-1.1',\n 'x-amz-target': `Logs_20140328.${action}`,\n },\n body,\n region: this.region,\n service: 'logs',\n credentials,\n });\n await httpRequest({\n url: this.endpoint,\n headers,\n body,\n timeoutMs: this.requestTimeoutMs,\n label: `CloudWatch ${action}`,\n });\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"entry-fields-BJkuPnIg.mjs","names":["merged: Record<string, unknown>"],"sources":["../src/transports/entry-fields.ts"],"sourcesContent":["const PAYLOAD_PREFIX = 'data_';\nconst UNSAFE_KEYS = new Set(['__proto__']);\n\n/**\n * Copies `core` and then the user payload into one object. The core fields stay\n * authoritative: a payload key that matches a core key (even one whose value is\n * undefined) or a reserved name is kept under a `data_` prefix instead. The\n * prefix is repeated until the name is free of core keys and of every other\n * payload key, so the result does not depend on key order and a payload's own\n * `data_level` stays where it is.\n */\nexport function mergeCoreFields(\n core: Record<string, unknown>,\n data: Record<string, unknown> | undefined,\n extraReserved: readonly string[] = []\n): Record<string, unknown> {\n const merged: Record<string, unknown> = { ...core };\n if (!data) return merged;\n const reserved = new Set([...Object.keys(core), ...extraReserved]);\n const payloadKeys = new Set(Object.keys(data));\n for (const key of payloadKeys) {\n if (UNSAFE_KEYS.has(key)) continue;\n let target = key;\n if (reserved.has(target)) {\n do {\n target = `${PAYLOAD_PREFIX}${target}`;\n } while (reserved.has(target) || payloadKeys.has(target));\n }\n merged[target] = data[key];\n }\n return merged;\n}\n"],"mappings":";AAAA,MAAM,iBAAiB;AACvB,MAAM,cAAc,IAAI,IAAI,CAAC,YAAY,CAAC;;;;;;;;;AAU1C,SAAgB,gBACd,MACA,MACA,gBAAmC,EAAE,EACZ;CACzB,MAAMA,SAAkC,EAAE,GAAG,MAAM;AACnD,KAAI,CAAC,KAAM,QAAO;CAClB,MAAM,WAAW,IAAI,IAAI,CAAC,GAAG,OAAO,KAAK,KAAK,EAAE,GAAG,cAAc,CAAC;CAClE,MAAM,cAAc,IAAI,IAAI,OAAO,KAAK,KAAK,CAAC;AAC9C,MAAK,MAAM,OAAO,aAAa;AAC7B,MAAI,YAAY,IAAI,IAAI,CAAE;EAC1B,IAAI,SAAS;AACb,MAAI,SAAS,IAAI,OAAO,CACtB;AACE,YAAS,GAAG,iBAAiB;SACtB,SAAS,IAAI,OAAO,IAAI,YAAY,IAAI,OAAO;AAE1D,SAAO,UAAU,KAAK;;AAExB,QAAO"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"entry-fields-BvOLFlJ4.js","names":["merged: Record<string, unknown>"],"sources":["../src/transports/entry-fields.ts"],"sourcesContent":["const PAYLOAD_PREFIX = 'data_';\nconst UNSAFE_KEYS = new Set(['__proto__']);\n\n/**\n * Copies `core` and then the user payload into one object. The core fields stay\n * authoritative: a payload key that matches a core key (even one whose value is\n * undefined) or a reserved name is kept under a `data_` prefix instead. The\n * prefix is repeated until the name is free of core keys and of every other\n * payload key, so the result does not depend on key order and a payload's own\n * `data_level` stays where it is.\n */\nexport function mergeCoreFields(\n core: Record<string, unknown>,\n data: Record<string, unknown> | undefined,\n extraReserved: readonly string[] = []\n): Record<string, unknown> {\n const merged: Record<string, unknown> = { ...core };\n if (!data) return merged;\n const reserved = new Set([...Object.keys(core), ...extraReserved]);\n const payloadKeys = new Set(Object.keys(data));\n for (const key of payloadKeys) {\n if (UNSAFE_KEYS.has(key)) continue;\n let target = key;\n if (reserved.has(target)) {\n do {\n target = `${PAYLOAD_PREFIX}${target}`;\n } while (reserved.has(target) || payloadKeys.has(target));\n }\n merged[target] = data[key];\n }\n return merged;\n}\n"],"mappings":";;AAAA,MAAM,iBAAiB;AACvB,MAAM,cAAc,IAAI,IAAI,CAAC,YAAY,CAAC;;;;;;;;;AAU1C,SAAgB,gBACd,MACA,MACA,gBAAmC,EAAE,EACZ;CACzB,MAAMA,SAAkC,EAAE,GAAG,MAAM;AACnD,KAAI,CAAC,KAAM,QAAO;CAClB,MAAM,WAAW,IAAI,IAAI,CAAC,GAAG,OAAO,KAAK,KAAK,EAAE,GAAG,cAAc,CAAC;CAClE,MAAM,cAAc,IAAI,IAAI,OAAO,KAAK,KAAK,CAAC;AAC9C,MAAK,MAAM,OAAO,aAAa;AAC7B,MAAI,YAAY,IAAI,IAAI,CAAE;EAC1B,IAAI,SAAS;AACb,MAAI,SAAS,IAAI,OAAO,CACtB;AACE,YAAS,GAAG,iBAAiB;SACtB,SAAS,IAAI,OAAO,IAAI,YAAY,IAAI,OAAO;AAE1D,SAAO,UAAU,KAAK;;AAExB,QAAO"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"gcp.transport-CHV8MGgz.js","names":["DEFAULT_REQUEST_TIMEOUT_MS","BatchBuffer","DEFAULT_MAX_BUFFER_SIZE","gcpEntry: Record<string, unknown>","mergeCoreFields","https","signature: string","httpRequest","stringifyForLog"],"sources":["../src/transports/gcp.transport.ts"],"sourcesContent":["/**\n * logixia — Google Cloud Logging (Stackdriver) transport\n *\n * Maps logixia log entries to the GCP Logging REST API format:\n * - Maps `level` → `severity` (INFO, WARNING, ERROR, CRITICAL…)\n * - Injects `logging.googleapis.com/trace` for Cloud Trace correlation\n * - Injects `logging.googleapis.com/spanId` and `traceSampled`\n * - Adds `logging.googleapis.com/sourceLocation` when available\n * - Supports structured `jsonPayload` and plain `textPayload`\n *\n * Auth: uses Application Default Credentials (ADC) — the `GOOGLE_APPLICATION_CREDENTIALS`\n * env var pointing to a service-account key file, or the metadata server on GCE/GKE.\n *\n * @example\n * ```ts\n * import { GCPTransport } from 'logixia';\n *\n * const logger = createLogger({\n * transports: {\n * gcp: new GCPTransport({\n * projectId: process.env.GOOGLE_CLOUD_PROJECT,\n * logName: 'projects/my-project/logs/api',\n * resource: { type: 'gce_instance', labels: { instance_id: '123' } },\n * }),\n * },\n * });\n * ```\n */\n\nimport * as https from 'node:https';\n\nimport type { IAsyncTransport, TransportLogEntry } from '../types/transport.types';\nimport { internalError } from '../utils/internal-log';\nimport { stringifyForLog } from '../utils/safe-stringify';\nimport {\n BatchBuffer,\n DEFAULT_MAX_BUFFER_SIZE,\n DEFAULT_REQUEST_TIMEOUT_MS,\n httpRequest,\n} from './batch-buffer';\nimport { mergeCoreFields } from './entry-fields';\n\nexport interface GCPMonitoredResource {\n type: string;\n labels?: Record<string, string>;\n}\n\nexport interface GCPTransportConfig {\n /** GCP project ID. Falls back to `GOOGLE_CLOUD_PROJECT` or `GCLOUD_PROJECT` env vars. */\n projectId?: string;\n /**\n * Full log name, e.g. `'projects/my-project/logs/api'`.\n * If omitted, defaults to `projects/{projectId}/logs/logixia`.\n */\n logName?: string;\n /** Monitored resource descriptor. Defaults to `global`. */\n resource?: GCPMonitoredResource;\n /**\n * Service account key JSON (parsed). If omitted, ADC is used\n * (GOOGLE_APPLICATION_CREDENTIALS env var or metadata server).\n */\n credentials?: {\n client_email: string;\n private_key: string;\n };\n /** Number of entries to batch. @default 200 */\n batchSize?: number;\n /** Flush interval in ms. @default 5000 */\n flushIntervalMs?: number;\n /** Abort a request that has not finished after this many ms. @default 10000 */\n requestTimeoutMs?: number;\n /** Max buffered entries; the oldest are dropped past this. @default 10000 */\n maxBufferSize?: number;\n level?: string;\n}\n\ntype GcpSeverity =\n | 'DEFAULT'\n | 'DEBUG'\n | 'INFO'\n | 'NOTICE'\n | 'WARNING'\n | 'ERROR'\n | 'CRITICAL'\n | 'ALERT'\n | 'EMERGENCY';\n\nfunction toGcpSeverity(level: string): GcpSeverity {\n switch (level.toLowerCase()) {\n case 'trace':\n case 'verbose':\n case 'debug':\n return 'DEBUG';\n case 'info':\n case 'log':\n return 'INFO';\n case 'warn':\n case 'warning':\n return 'WARNING';\n case 'error':\n return 'ERROR';\n case 'critical':\n case 'fatal':\n return 'CRITICAL';\n default:\n return 'DEFAULT';\n }\n}\n\n/**\n * Google Cloud Logging transport with trace correlation and GCP severity mapping.\n */\nexport class GCPTransport implements IAsyncTransport {\n public readonly name = 'gcp';\n public readonly batchSize: number;\n public readonly flushInterval: number;\n public readonly level: string | undefined;\n\n private readonly buffer: BatchBuffer<TransportLogEntry>;\n private readonly requestTimeoutMs: number;\n private flushTimer: NodeJS.Timeout | null = null;\n private accessToken: string | null = null;\n private tokenExpiry = 0;\n\n private readonly projectId: string;\n private readonly logName: string;\n private readonly resource: GCPMonitoredResource;\n private readonly credentials: { client_email: string; private_key: string } | undefined;\n\n constructor(config: GCPTransportConfig) {\n this.projectId =\n config.projectId ??\n process.env['GOOGLE_CLOUD_PROJECT'] ??\n process.env['GCLOUD_PROJECT'] ??\n 'unknown-project';\n this.logName = config.logName ?? `projects/${this.projectId}/logs/logixia`;\n this.resource = config.resource ?? { type: 'global' };\n this.credentials = config.credentials;\n this.batchSize = config.batchSize ?? 200;\n this.flushInterval = config.flushIntervalMs ?? 5000;\n this.level = config.level;\n this.requestTimeoutMs = config.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;\n this.buffer = new BatchBuffer<TransportLogEntry>({\n name: 'GCPTransport',\n batchSize: this.batchSize,\n maxBufferSize: config.maxBufferSize ?? DEFAULT_MAX_BUFFER_SIZE,\n send: (entries) => this.writeEntries(entries),\n });\n\n this.flushTimer = setInterval(() => {\n this.flush().catch(() => {});\n }, this.flushInterval);\n if (this.flushTimer.unref) this.flushTimer.unref();\n }\n\n write(entry: TransportLogEntry): void {\n this.buffer.push(entry);\n this.buffer.flushIfFull();\n }\n\n flush(): Promise<void> {\n return this.buffer.flush();\n }\n\n /**\n * Flush remaining entries and stop the interval timer on shutdown. Without\n * this the manager's close() skipped the transport (close was undefined) and\n * buffered entries were lost on deploy. Waits for any in-flight send first.\n */\n async close(): Promise<void> {\n if (this.flushTimer) {\n clearInterval(this.flushTimer);\n this.flushTimer = null;\n }\n await this.buffer.close();\n }\n\n private buildLogEntry(entry: TransportLogEntry): Record<string, unknown> {\n const gcpEntry: Record<string, unknown> = {\n logName: this.logName,\n resource: this.resource,\n severity: toGcpSeverity(entry.level),\n timestamp: entry.timestamp ?? new Date().toISOString(),\n jsonPayload: mergeCoreFields(\n { message: entry.message, appName: entry.appName, context: entry.context },\n entry.data\n ),\n };\n\n // GCP Cloud Trace correlation\n if (entry.traceId) {\n gcpEntry['trace'] = `projects/${this.projectId}/traces/${entry.traceId}`;\n gcpEntry['traceSampled'] = true;\n }\n\n return gcpEntry;\n }\n\n private async getAccessToken(): Promise<string | null> {\n if (this.accessToken && Date.now() < this.tokenExpiry) return this.accessToken;\n\n // Try ADC metadata server (GCE/GKE/Cloud Run)\n try {\n const token = await this.fetchFromMetadataServer();\n if (token) {\n this.accessToken = token;\n this.tokenExpiry = Date.now() + 55 * 60 * 1000; // 55 minutes\n return this.accessToken;\n }\n } catch {\n /* fall through to service account */\n }\n\n // Try service account key\n if (this.credentials) {\n try {\n const token = await this.fetchServiceAccountToken();\n if (token) {\n this.accessToken = token;\n this.tokenExpiry = Date.now() + 55 * 60 * 1000;\n return this.accessToken;\n }\n } catch (err) {\n internalError('GCPTransport service account token error', err);\n }\n }\n\n return null;\n }\n\n private fetchFromMetadataServer(): Promise<string | null> {\n return new Promise((resolve, reject) => {\n const req = https.request(\n {\n hostname: 'metadata.google.internal',\n path: '/computeMetadata/v1/instance/service-accounts/default/token',\n headers: { 'Metadata-Flavor': 'Google' },\n timeout: 3000,\n },\n (res) => {\n let raw = '';\n res.on('data', (c: Buffer) => (raw += c.toString()));\n res.on('end', () => {\n if (res.statusCode === 200) {\n try {\n const parsed = JSON.parse(raw) as { access_token?: string };\n resolve(parsed.access_token ?? null);\n } catch {\n resolve(null);\n }\n } else {\n resolve(null);\n }\n });\n }\n );\n req.on('error', reject);\n req.on('timeout', () => {\n req.destroy();\n reject(new Error('metadata timeout'));\n });\n req.end();\n });\n }\n\n private fetchServiceAccountToken(): Promise<string | null> {\n // Minimal JWT creation for service account — only for environments without\n // the full Google Auth Library. For production workloads, prefer ADC.\n if (!this.credentials) return Promise.resolve(null);\n\n const iat = Math.floor(Date.now() / 1000);\n const exp = iat + 3600;\n const scope = 'https://www.googleapis.com/auth/logging.write';\n\n const header = Buffer.from(JSON.stringify({ alg: 'RS256', typ: 'JWT' })).toString('base64url');\n const payload = Buffer.from(\n JSON.stringify({\n iss: this.credentials.client_email,\n scope,\n aud: 'https://oauth2.googleapis.com/token',\n exp,\n iat,\n })\n ).toString('base64url');\n\n const signingInput = `${header}.${payload}`;\n\n let signature: string;\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const sign = require('node:crypto').createSign('RSA-SHA256');\n sign.update(signingInput);\n signature = sign.sign(this.credentials.private_key, 'base64url') as string;\n } catch {\n return Promise.resolve(null);\n }\n\n const jwt = `${signingInput}.${signature}`;\n const body = `grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=${jwt}`;\n\n return httpRequest({\n url: new URL('https://oauth2.googleapis.com/token'),\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body,\n timeoutMs: this.requestTimeoutMs,\n label: 'GCP token request',\n }).then(\n (res) => (JSON.parse(res.body) as { access_token?: string }).access_token ?? null,\n () => null\n );\n }\n\n private async writeEntries(entries: TransportLogEntry[]): Promise<void> {\n const token = await this.getAccessToken();\n if (!token) {\n throw new Error('GCPTransport: no access token available');\n }\n\n const body = stringifyForLog({\n logName: this.logName,\n resource: this.resource,\n entries: entries.map((e) => this.buildLogEntry(e)),\n });\n\n await httpRequest({\n url: new URL('https://logging.googleapis.com/v2/entries:write'),\n headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },\n body,\n timeoutMs: this.requestTimeoutMs,\n label: 'GCP Logging API',\n });\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"gcp.transport-DBX5TPIy.mjs","names":["gcpEntry: Record<string, unknown>","signature: string"],"sources":["../src/transports/gcp.transport.ts"],"sourcesContent":["/**\n * logixia — Google Cloud Logging (Stackdriver) transport\n *\n * Maps logixia log entries to the GCP Logging REST API format:\n * - Maps `level` → `severity` (INFO, WARNING, ERROR, CRITICAL…)\n * - Injects `logging.googleapis.com/trace` for Cloud Trace correlation\n * - Injects `logging.googleapis.com/spanId` and `traceSampled`\n * - Adds `logging.googleapis.com/sourceLocation` when available\n * - Supports structured `jsonPayload` and plain `textPayload`\n *\n * Auth: uses Application Default Credentials (ADC) — the `GOOGLE_APPLICATION_CREDENTIALS`\n * env var pointing to a service-account key file, or the metadata server on GCE/GKE.\n *\n * @example\n * ```ts\n * import { GCPTransport } from 'logixia';\n *\n * const logger = createLogger({\n * transports: {\n * gcp: new GCPTransport({\n * projectId: process.env.GOOGLE_CLOUD_PROJECT,\n * logName: 'projects/my-project/logs/api',\n * resource: { type: 'gce_instance', labels: { instance_id: '123' } },\n * }),\n * },\n * });\n * ```\n */\n\nimport * as https from 'node:https';\n\nimport type { IAsyncTransport, TransportLogEntry } from '../types/transport.types';\nimport { internalError } from '../utils/internal-log';\nimport { stringifyForLog } from '../utils/safe-stringify';\nimport {\n BatchBuffer,\n DEFAULT_MAX_BUFFER_SIZE,\n DEFAULT_REQUEST_TIMEOUT_MS,\n httpRequest,\n} from './batch-buffer';\nimport { mergeCoreFields } from './entry-fields';\n\nexport interface GCPMonitoredResource {\n type: string;\n labels?: Record<string, string>;\n}\n\nexport interface GCPTransportConfig {\n /** GCP project ID. Falls back to `GOOGLE_CLOUD_PROJECT` or `GCLOUD_PROJECT` env vars. */\n projectId?: string;\n /**\n * Full log name, e.g. `'projects/my-project/logs/api'`.\n * If omitted, defaults to `projects/{projectId}/logs/logixia`.\n */\n logName?: string;\n /** Monitored resource descriptor. Defaults to `global`. */\n resource?: GCPMonitoredResource;\n /**\n * Service account key JSON (parsed). If omitted, ADC is used\n * (GOOGLE_APPLICATION_CREDENTIALS env var or metadata server).\n */\n credentials?: {\n client_email: string;\n private_key: string;\n };\n /** Number of entries to batch. @default 200 */\n batchSize?: number;\n /** Flush interval in ms. @default 5000 */\n flushIntervalMs?: number;\n /** Abort a request that has not finished after this many ms. @default 10000 */\n requestTimeoutMs?: number;\n /** Max buffered entries; the oldest are dropped past this. @default 10000 */\n maxBufferSize?: number;\n level?: string;\n}\n\ntype GcpSeverity =\n | 'DEFAULT'\n | 'DEBUG'\n | 'INFO'\n | 'NOTICE'\n | 'WARNING'\n | 'ERROR'\n | 'CRITICAL'\n | 'ALERT'\n | 'EMERGENCY';\n\nfunction toGcpSeverity(level: string): GcpSeverity {\n switch (level.toLowerCase()) {\n case 'trace':\n case 'verbose':\n case 'debug':\n return 'DEBUG';\n case 'info':\n case 'log':\n return 'INFO';\n case 'warn':\n case 'warning':\n return 'WARNING';\n case 'error':\n return 'ERROR';\n case 'critical':\n case 'fatal':\n return 'CRITICAL';\n default:\n return 'DEFAULT';\n }\n}\n\n/**\n * Google Cloud Logging transport with trace correlation and GCP severity mapping.\n */\nexport class GCPTransport implements IAsyncTransport {\n public readonly name = 'gcp';\n public readonly batchSize: number;\n public readonly flushInterval: number;\n public readonly level: string | undefined;\n\n private readonly buffer: BatchBuffer<TransportLogEntry>;\n private readonly requestTimeoutMs: number;\n private flushTimer: NodeJS.Timeout | null = null;\n private accessToken: string | null = null;\n private tokenExpiry = 0;\n\n private readonly projectId: string;\n private readonly logName: string;\n private readonly resource: GCPMonitoredResource;\n private readonly credentials: { client_email: string; private_key: string } | undefined;\n\n constructor(config: GCPTransportConfig) {\n this.projectId =\n config.projectId ??\n process.env['GOOGLE_CLOUD_PROJECT'] ??\n process.env['GCLOUD_PROJECT'] ??\n 'unknown-project';\n this.logName = config.logName ?? `projects/${this.projectId}/logs/logixia`;\n this.resource = config.resource ?? { type: 'global' };\n this.credentials = config.credentials;\n this.batchSize = config.batchSize ?? 200;\n this.flushInterval = config.flushIntervalMs ?? 5000;\n this.level = config.level;\n this.requestTimeoutMs = config.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;\n this.buffer = new BatchBuffer<TransportLogEntry>({\n name: 'GCPTransport',\n batchSize: this.batchSize,\n maxBufferSize: config.maxBufferSize ?? DEFAULT_MAX_BUFFER_SIZE,\n send: (entries) => this.writeEntries(entries),\n });\n\n this.flushTimer = setInterval(() => {\n this.flush().catch(() => {});\n }, this.flushInterval);\n if (this.flushTimer.unref) this.flushTimer.unref();\n }\n\n write(entry: TransportLogEntry): void {\n this.buffer.push(entry);\n this.buffer.flushIfFull();\n }\n\n flush(): Promise<void> {\n return this.buffer.flush();\n }\n\n /**\n * Flush remaining entries and stop the interval timer on shutdown. Without\n * this the manager's close() skipped the transport (close was undefined) and\n * buffered entries were lost on deploy. Waits for any in-flight send first.\n */\n async close(): Promise<void> {\n if (this.flushTimer) {\n clearInterval(this.flushTimer);\n this.flushTimer = null;\n }\n await this.buffer.close();\n }\n\n private buildLogEntry(entry: TransportLogEntry): Record<string, unknown> {\n const gcpEntry: Record<string, unknown> = {\n logName: this.logName,\n resource: this.resource,\n severity: toGcpSeverity(entry.level),\n timestamp: entry.timestamp ?? new Date().toISOString(),\n jsonPayload: mergeCoreFields(\n { message: entry.message, appName: entry.appName, context: entry.context },\n entry.data\n ),\n };\n\n // GCP Cloud Trace correlation\n if (entry.traceId) {\n gcpEntry['trace'] = `projects/${this.projectId}/traces/${entry.traceId}`;\n gcpEntry['traceSampled'] = true;\n }\n\n return gcpEntry;\n }\n\n private async getAccessToken(): Promise<string | null> {\n if (this.accessToken && Date.now() < this.tokenExpiry) return this.accessToken;\n\n // Try ADC metadata server (GCE/GKE/Cloud Run)\n try {\n const token = await this.fetchFromMetadataServer();\n if (token) {\n this.accessToken = token;\n this.tokenExpiry = Date.now() + 55 * 60 * 1000; // 55 minutes\n return this.accessToken;\n }\n } catch {\n /* fall through to service account */\n }\n\n // Try service account key\n if (this.credentials) {\n try {\n const token = await this.fetchServiceAccountToken();\n if (token) {\n this.accessToken = token;\n this.tokenExpiry = Date.now() + 55 * 60 * 1000;\n return this.accessToken;\n }\n } catch (err) {\n internalError('GCPTransport service account token error', err);\n }\n }\n\n return null;\n }\n\n private fetchFromMetadataServer(): Promise<string | null> {\n return new Promise((resolve, reject) => {\n const req = https.request(\n {\n hostname: 'metadata.google.internal',\n path: '/computeMetadata/v1/instance/service-accounts/default/token',\n headers: { 'Metadata-Flavor': 'Google' },\n timeout: 3000,\n },\n (res) => {\n let raw = '';\n res.on('data', (c: Buffer) => (raw += c.toString()));\n res.on('end', () => {\n if (res.statusCode === 200) {\n try {\n const parsed = JSON.parse(raw) as { access_token?: string };\n resolve(parsed.access_token ?? null);\n } catch {\n resolve(null);\n }\n } else {\n resolve(null);\n }\n });\n }\n );\n req.on('error', reject);\n req.on('timeout', () => {\n req.destroy();\n reject(new Error('metadata timeout'));\n });\n req.end();\n });\n }\n\n private fetchServiceAccountToken(): Promise<string | null> {\n // Minimal JWT creation for service account — only for environments without\n // the full Google Auth Library. For production workloads, prefer ADC.\n if (!this.credentials) return Promise.resolve(null);\n\n const iat = Math.floor(Date.now() / 1000);\n const exp = iat + 3600;\n const scope = 'https://www.googleapis.com/auth/logging.write';\n\n const header = Buffer.from(JSON.stringify({ alg: 'RS256', typ: 'JWT' })).toString('base64url');\n const payload = Buffer.from(\n JSON.stringify({\n iss: this.credentials.client_email,\n scope,\n aud: 'https://oauth2.googleapis.com/token',\n exp,\n iat,\n })\n ).toString('base64url');\n\n const signingInput = `${header}.${payload}`;\n\n let signature: string;\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const sign = require('node:crypto').createSign('RSA-SHA256');\n sign.update(signingInput);\n signature = sign.sign(this.credentials.private_key, 'base64url') as string;\n } catch {\n return Promise.resolve(null);\n }\n\n const jwt = `${signingInput}.${signature}`;\n const body = `grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=${jwt}`;\n\n return httpRequest({\n url: new URL('https://oauth2.googleapis.com/token'),\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body,\n timeoutMs: this.requestTimeoutMs,\n label: 'GCP token request',\n }).then(\n (res) => (JSON.parse(res.body) as { access_token?: string }).access_token ?? null,\n () => null\n );\n }\n\n private async writeEntries(entries: TransportLogEntry[]): Promise<void> {\n const token = await this.getAccessToken();\n if (!token) {\n throw new Error('GCPTransport: no access token available');\n }\n\n const body = stringifyForLog({\n logName: this.logName,\n resource: this.resource,\n entries: entries.map((e) => this.buildLogEntry(e)),\n });\n\n await httpRequest({\n url: new URL('https://logging.googleapis.com/v2/entries:write'),\n headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },\n body,\n timeoutMs: this.requestTimeoutMs,\n label: 'GCP Logging API',\n });\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"gcp.transport-m4fVw0b1.d.ts","names":[],"sources":["../src/transports/gcp.transport.ts"],"sourcesContent":[],"mappings":";;;;UA0CiB,oBAAA;;WAEN;;UAGM,kBAAA;;;;;;;;;aASJ;;;;;;;;;;;;;;;;;;;;;;cAwDA,YAAA,YAAwB;;;;;;;;;;;;;;sBAiBf;eA0BP;WAKJ;;;;;;WASM"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"gcp.transport-zzNyIoih.d.mts","names":[],"sources":["../src/transports/gcp.transport.ts"],"sourcesContent":[],"mappings":";;;;UA0CiB,oBAAA;;WAEN;;UAGM,kBAAA;;;;;;;;;aASJ;;;;;;;;;;;;;;;;;;;;;;cAwDA,YAAA,YAAwB;;;;;;;;;;;;;;sBAiBf;eA0BP;WAKJ;;;;;;WASM"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-BPwEisy4.d.mts","names":[],"sources":["../src/types/http.types.ts","../src/types/index.ts"],"sourcesContent":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-nZEeCr3X.d.ts","names":[],"sources":["../src/types/http.types.ts","../src/types/index.ts"],"sourcesContent":[],"mappings":"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"}
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
//#region src/utils/internal-log.ts
|
|
3
|
-
/**
|
|
4
|
-
* Internal logging helpers for use within the logixia library itself.
|
|
5
|
-
*
|
|
6
|
-
* These functions write directly to stderr/stdout without going through
|
|
7
|
-
* LogixiaLogger — this avoids circular dependencies and ensures internal
|
|
8
|
-
* diagnostics still surface even when the logger is misconfigured.
|
|
9
|
-
*
|
|
10
|
-
* Library code must NEVER call console.log/warn/error directly. Use these
|
|
11
|
-
* helpers instead so that internal output can be silenced in tests by setting
|
|
12
|
-
* the LOGIXIA_SILENT_INTERNAL=1 environment variable.
|
|
13
|
-
*/
|
|
14
|
-
/**
|
|
15
|
-
* Read the silence flag on each call rather than caching it at import time, so
|
|
16
|
-
* setting LOGIXIA_SILENT_INTERNAL=1 AFTER the module is first imported (e.g. in
|
|
17
|
-
* a test setup file) still takes effect — the documented test-silencing
|
|
18
|
-
* behavior was previously unreliable because the value was frozen at load.
|
|
19
|
-
*/
|
|
20
|
-
function isSilent() {
|
|
21
|
-
return process.env.LOGIXIA_SILENT_INTERNAL === "1";
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Emit an internal debug/info message to stderr.
|
|
25
|
-
* Use for field-enable/disable notifications that a developer might want to see
|
|
26
|
-
* during development but should not appear in production log streams.
|
|
27
|
-
*/
|
|
28
|
-
function internalLog(message) {
|
|
29
|
-
if (!isSilent()) process.stderr.write(`[logixia] ${message}\n`);
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Emit an internal warning to stderr.
|
|
33
|
-
* Use when something is misconfigured but logixia can continue operating.
|
|
34
|
-
*/
|
|
35
|
-
function internalWarn(message) {
|
|
36
|
-
if (!isSilent()) process.stderr.write(`[logixia:warn] ${message}\n`);
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Emit an internal error to stderr.
|
|
40
|
-
* Use when a transport write fails or a serious internal error occurs.
|
|
41
|
-
*/
|
|
42
|
-
function internalError(message, error) {
|
|
43
|
-
if (!isSilent()) {
|
|
44
|
-
let errStr = "";
|
|
45
|
-
if (error instanceof Error) errStr = ` — ${error.message}`;
|
|
46
|
-
else if (error != null) errStr = ` — ${String(error)}`;
|
|
47
|
-
process.stderr.write(`[logixia:error] ${message}${errStr}\n`);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
//#endregion
|
|
52
|
-
Object.defineProperty(exports, 'internalError', {
|
|
53
|
-
enumerable: true,
|
|
54
|
-
get: function () {
|
|
55
|
-
return internalError;
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
Object.defineProperty(exports, 'internalLog', {
|
|
59
|
-
enumerable: true,
|
|
60
|
-
get: function () {
|
|
61
|
-
return internalLog;
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
Object.defineProperty(exports, 'internalWarn', {
|
|
65
|
-
enumerable: true,
|
|
66
|
-
get: function () {
|
|
67
|
-
return internalWarn;
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
//# sourceMappingURL=internal-log-BUJYMZbE.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"internal-log-BUJYMZbE.js","names":[],"sources":["../src/utils/internal-log.ts"],"sourcesContent":["/**\n * Internal logging helpers for use within the logixia library itself.\n *\n * These functions write directly to stderr/stdout without going through\n * LogixiaLogger — this avoids circular dependencies and ensures internal\n * diagnostics still surface even when the logger is misconfigured.\n *\n * Library code must NEVER call console.log/warn/error directly. Use these\n * helpers instead so that internal output can be silenced in tests by setting\n * the LOGIXIA_SILENT_INTERNAL=1 environment variable.\n */\n\n/**\n * Read the silence flag on each call rather than caching it at import time, so\n * setting LOGIXIA_SILENT_INTERNAL=1 AFTER the module is first imported (e.g. in\n * a test setup file) still takes effect — the documented test-silencing\n * behavior was previously unreliable because the value was frozen at load.\n */\nfunction isSilent(): boolean {\n return process.env.LOGIXIA_SILENT_INTERNAL === '1';\n}\n\n/**\n * Emit an internal debug/info message to stderr.\n * Use for field-enable/disable notifications that a developer might want to see\n * during development but should not appear in production log streams.\n */\nexport function internalLog(message: string): void {\n if (!isSilent()) {\n process.stderr.write(`[logixia] ${message}\\n`);\n }\n}\n\n/**\n * Emit an internal warning to stderr.\n * Use when something is misconfigured but logixia can continue operating.\n */\nexport function internalWarn(message: string): void {\n if (!isSilent()) {\n process.stderr.write(`[logixia:warn] ${message}\\n`);\n }\n}\n\n/**\n * Emit an internal error to stderr.\n * Use when a transport write fails or a serious internal error occurs.\n */\nexport function internalError(message: string, error?: unknown): void {\n if (!isSilent()) {\n let errStr = '';\n if (error instanceof Error) {\n errStr = ` — ${error.message}`;\n } else if (error != null) {\n errStr = ` — ${String(error)}`;\n }\n process.stderr.write(`[logixia:error] ${message}${errStr}\\n`);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAkBA,SAAS,WAAoB;AAC3B,QAAO,QAAQ,IAAI,4BAA4B;;;;;;;AAQjD,SAAgB,YAAY,SAAuB;AACjD,KAAI,CAAC,UAAU,CACb,SAAQ,OAAO,MAAM,aAAa,QAAQ,IAAI;;;;;;AAQlD,SAAgB,aAAa,SAAuB;AAClD,KAAI,CAAC,UAAU,CACb,SAAQ,OAAO,MAAM,kBAAkB,QAAQ,IAAI;;;;;;AAQvD,SAAgB,cAAc,SAAiB,OAAuB;AACpE,KAAI,CAAC,UAAU,EAAE;EACf,IAAI,SAAS;AACb,MAAI,iBAAiB,MACnB,UAAS,MAAM,MAAM;WACZ,SAAS,KAClB,UAAS,MAAM,OAAO,MAAM;AAE9B,UAAQ,OAAO,MAAM,mBAAmB,UAAU,OAAO,IAAI"}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
//#region src/utils/internal-log.ts
|
|
2
|
-
/**
|
|
3
|
-
* Internal logging helpers for use within the logixia library itself.
|
|
4
|
-
*
|
|
5
|
-
* These functions write directly to stderr/stdout without going through
|
|
6
|
-
* LogixiaLogger — this avoids circular dependencies and ensures internal
|
|
7
|
-
* diagnostics still surface even when the logger is misconfigured.
|
|
8
|
-
*
|
|
9
|
-
* Library code must NEVER call console.log/warn/error directly. Use these
|
|
10
|
-
* helpers instead so that internal output can be silenced in tests by setting
|
|
11
|
-
* the LOGIXIA_SILENT_INTERNAL=1 environment variable.
|
|
12
|
-
*/
|
|
13
|
-
/**
|
|
14
|
-
* Read the silence flag on each call rather than caching it at import time, so
|
|
15
|
-
* setting LOGIXIA_SILENT_INTERNAL=1 AFTER the module is first imported (e.g. in
|
|
16
|
-
* a test setup file) still takes effect — the documented test-silencing
|
|
17
|
-
* behavior was previously unreliable because the value was frozen at load.
|
|
18
|
-
*/
|
|
19
|
-
function isSilent() {
|
|
20
|
-
return process.env.LOGIXIA_SILENT_INTERNAL === "1";
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Emit an internal debug/info message to stderr.
|
|
24
|
-
* Use for field-enable/disable notifications that a developer might want to see
|
|
25
|
-
* during development but should not appear in production log streams.
|
|
26
|
-
*/
|
|
27
|
-
function internalLog(message) {
|
|
28
|
-
if (!isSilent()) process.stderr.write(`[logixia] ${message}\n`);
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Emit an internal warning to stderr.
|
|
32
|
-
* Use when something is misconfigured but logixia can continue operating.
|
|
33
|
-
*/
|
|
34
|
-
function internalWarn(message) {
|
|
35
|
-
if (!isSilent()) process.stderr.write(`[logixia:warn] ${message}\n`);
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Emit an internal error to stderr.
|
|
39
|
-
* Use when a transport write fails or a serious internal error occurs.
|
|
40
|
-
*/
|
|
41
|
-
function internalError(message, error) {
|
|
42
|
-
if (!isSilent()) {
|
|
43
|
-
let errStr = "";
|
|
44
|
-
if (error instanceof Error) errStr = ` — ${error.message}`;
|
|
45
|
-
else if (error != null) errStr = ` — ${String(error)}`;
|
|
46
|
-
process.stderr.write(`[logixia:error] ${message}${errStr}\n`);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
//#endregion
|
|
51
|
-
export { internalLog as n, internalWarn as r, internalError as t };
|
|
52
|
-
//# sourceMappingURL=internal-log-Cm8SOWSV.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"internal-log-Cm8SOWSV.mjs","names":[],"sources":["../src/utils/internal-log.ts"],"sourcesContent":["/**\n * Internal logging helpers for use within the logixia library itself.\n *\n * These functions write directly to stderr/stdout without going through\n * LogixiaLogger — this avoids circular dependencies and ensures internal\n * diagnostics still surface even when the logger is misconfigured.\n *\n * Library code must NEVER call console.log/warn/error directly. Use these\n * helpers instead so that internal output can be silenced in tests by setting\n * the LOGIXIA_SILENT_INTERNAL=1 environment variable.\n */\n\n/**\n * Read the silence flag on each call rather than caching it at import time, so\n * setting LOGIXIA_SILENT_INTERNAL=1 AFTER the module is first imported (e.g. in\n * a test setup file) still takes effect — the documented test-silencing\n * behavior was previously unreliable because the value was frozen at load.\n */\nfunction isSilent(): boolean {\n return process.env.LOGIXIA_SILENT_INTERNAL === '1';\n}\n\n/**\n * Emit an internal debug/info message to stderr.\n * Use for field-enable/disable notifications that a developer might want to see\n * during development but should not appear in production log streams.\n */\nexport function internalLog(message: string): void {\n if (!isSilent()) {\n process.stderr.write(`[logixia] ${message}\\n`);\n }\n}\n\n/**\n * Emit an internal warning to stderr.\n * Use when something is misconfigured but logixia can continue operating.\n */\nexport function internalWarn(message: string): void {\n if (!isSilent()) {\n process.stderr.write(`[logixia:warn] ${message}\\n`);\n }\n}\n\n/**\n * Emit an internal error to stderr.\n * Use when a transport write fails or a serious internal error occurs.\n */\nexport function internalError(message: string, error?: unknown): void {\n if (!isSilent()) {\n let errStr = '';\n if (error instanceof Error) {\n errStr = ` — ${error.message}`;\n } else if (error != null) {\n errStr = ` — ${String(error)}`;\n }\n process.stderr.write(`[logixia:error] ${message}${errStr}\\n`);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAkBA,SAAS,WAAoB;AAC3B,QAAO,QAAQ,IAAI,4BAA4B;;;;;;;AAQjD,SAAgB,YAAY,SAAuB;AACjD,KAAI,CAAC,UAAU,CACb,SAAQ,OAAO,MAAM,aAAa,QAAQ,IAAI;;;;;;AAQlD,SAAgB,aAAa,SAAuB;AAClD,KAAI,CAAC,UAAU,CACb,SAAQ,OAAO,MAAM,kBAAkB,QAAQ,IAAI;;;;;;AAQvD,SAAgB,cAAc,SAAiB,OAAuB;AACpE,KAAI,CAAC,UAAU,EAAE;EACf,IAAI,SAAS;AACb,MAAI,iBAAiB,MACnB,UAAS,MAAM,MAAM;WACZ,SAAS,KAClB,UAAS,MAAM,OAAO,MAAM;AAE9B,UAAQ,OAAO,MAAM,mBAAmB,UAAU,OAAO,IAAI"}
|