@logickernel/logger 0.2.0
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 +149 -0
- package/dist/index.cjs +120 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +14 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +94 -0
- package/dist/index.js.map +1 -0
- package/package.json +34 -0
package/README.md
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
## @logickernel/logger
|
|
2
|
+
|
|
3
|
+
Lightweight Node.js logger that automatically routes logs to **Google Cloud Logging** (when available) or the **local console**. Designed for small services and tools where you want structured logs in GCP without wiring up a full logging stack.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import logger from "@logickernel/logger";
|
|
7
|
+
|
|
8
|
+
logger.info("server started", { port: 3000 });
|
|
9
|
+
logger.debug("user action", { userId: "123", action: "login" });
|
|
10
|
+
logger.error(new Error("something went wrong"));
|
|
11
|
+
logger.warning("disk space low", { used: "92%", mount: "/data" });
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
> Your code never has to care whether it’s running on Cloud Run / GCP or locally – the logger picks the right backend at startup.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## 1. Introduction
|
|
19
|
+
|
|
20
|
+
- **What it is**: A tiny logging helper with the full GCP severity ladder and a smart backend:
|
|
21
|
+
- In **GCP** (or when `SYSTEM_LOGS=gcp`): writes to Google Cloud Logging with proper severities and structured `jsonPayload` when a context object is provided.
|
|
22
|
+
- Otherwise: writes to the local console with emoji prefixes, a local timestamp, and the context object inlined as compact JSON.
|
|
23
|
+
- **Why it exists**: To avoid sprinkling environment-specific logging logic across your codebase. You import one `logger` and use it everywhere.
|
|
24
|
+
|
|
25
|
+
**Key features**
|
|
26
|
+
|
|
27
|
+
- **Zero config in GCP**: Uses `K_SERVICE` and `GCP_PROJECT` from the environment.
|
|
28
|
+
- **Auto backend selection**: GCP vs console decided once at module load.
|
|
29
|
+
- **Full severity ladder**: `debug`, `info`, `notice`, `warning`, `error`, `critical`, `alert`, `emergency`.
|
|
30
|
+
- **Structured context**: Pass a plain object as the last argument — it becomes a `jsonPayload` in GCP (queryable by field) and compact inline JSON in the console.
|
|
31
|
+
- **Tiny API**: One default export (`logger`) plus a `formatMessage` helper if you need it.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 2. Local Setup (Development)
|
|
36
|
+
|
|
37
|
+
### Prerequisites
|
|
38
|
+
|
|
39
|
+
- **Node.js**: v18+ recommended (any actively supported LTS should work).
|
|
40
|
+
- **npm** (or compatible package manager).
|
|
41
|
+
|
|
42
|
+
### Clone and install
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
git clone https://github.com/logickernel/logger.git
|
|
46
|
+
cd logger
|
|
47
|
+
npm install
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Useful scripts
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# Run tests
|
|
54
|
+
npm test
|
|
55
|
+
|
|
56
|
+
# Type-check
|
|
57
|
+
npm run typecheck
|
|
58
|
+
|
|
59
|
+
# Build the library
|
|
60
|
+
npm run build
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## 3. Installation & Usage (as a Library)
|
|
66
|
+
|
|
67
|
+
### Install from npm
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
npm install @logickernel/logger
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Basic usage
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
import logger from "@logickernel/logger";
|
|
77
|
+
|
|
78
|
+
logger.info("server started", { port: 3000 });
|
|
79
|
+
logger.debug("user action", { userId: "123", action: "login" });
|
|
80
|
+
logger.warning("disk space low", { used: "92%", mount: "/data" });
|
|
81
|
+
logger.error(new Error("oops"));
|
|
82
|
+
logger.critical("primary db unreachable", { host: "db-1" });
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
The default export is a **singleton** whose backend is chosen at module load:
|
|
86
|
+
|
|
87
|
+
- **GCP backend** is used when:
|
|
88
|
+
- `SYSTEM_LOGS=gcp`, or
|
|
89
|
+
- `K_SERVICE` is set (e.g. Cloud Run)
|
|
90
|
+
- Otherwise, the **console backend** is used.
|
|
91
|
+
|
|
92
|
+
### Severity methods
|
|
93
|
+
|
|
94
|
+
| Method | GCP severity | Console emoji |
|
|
95
|
+
|---|---|---|
|
|
96
|
+
| `debug` | `DEBUG` | 🐞 |
|
|
97
|
+
| `info` | `INFO` | ℹ️ |
|
|
98
|
+
| `notice` | `NOTICE` | *️⃣ |
|
|
99
|
+
| `warning` | `WARNING` | ⚠️ |
|
|
100
|
+
| `error` | `ERROR` | ⛔️ |
|
|
101
|
+
| `critical` | `CRITICAL` | ❗️ |
|
|
102
|
+
| `alert` | `ALERT` | ‼️ |
|
|
103
|
+
| `emergency` | `EMERGENCY` | 🚨 |
|
|
104
|
+
|
|
105
|
+
### Structured context
|
|
106
|
+
|
|
107
|
+
Pass a plain object as the last argument to attach structured data to a log entry:
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
logger.info("request complete", { method: "GET", path: "/api/users", status: 200, ms: 42 });
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
- **GCP backend**: written as `jsonPayload` — fields are indexed and queryable in Cloud Logging.
|
|
114
|
+
- **Console backend**: inlined as compact JSON on the same line.
|
|
115
|
+
|
|
116
|
+
### Console format
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
🐞 2026-02-26 13:04:22.341 user action { "userId": "123", "action": "login" }
|
|
120
|
+
⚠️ 2026-02-26 13:04:22.512 disk space low { "used": "92%", "mount": "/data" }
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Environment variables
|
|
124
|
+
|
|
125
|
+
- `SYSTEM_LOGS=gcp`
|
|
126
|
+
Force GCP logging even if `K_SERVICE` is not set.
|
|
127
|
+
|
|
128
|
+
- `K_SERVICE`
|
|
129
|
+
Used as the log name in Google Cloud Logging. If not set, `"app"` is used.
|
|
130
|
+
|
|
131
|
+
- `GCP_PROJECT`
|
|
132
|
+
Project ID for Google Cloud Logging. Required when using the GCP backend.
|
|
133
|
+
|
|
134
|
+
### Named exports
|
|
135
|
+
|
|
136
|
+
```ts
|
|
137
|
+
import logger, { Logger, formatMessage } from "@logickernel/logger";
|
|
138
|
+
|
|
139
|
+
const myLogger: Logger = logger;
|
|
140
|
+
const message = formatMessage(["hello", { id: 1 }]); // "hello {"id":1}"
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## 4. Additional Resources
|
|
146
|
+
|
|
147
|
+
- **Package**: `@logickernel/logger` on npm.
|
|
148
|
+
- **License**: MIT (see `LICENSE` in this repository).
|
|
149
|
+
- **Contributions**: Feel free to open issues or pull requests if you’d like improvements (extra transports, richer metadata, etc.).
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
default: () => index_default,
|
|
24
|
+
formatMessage: () => formatMessage,
|
|
25
|
+
logger: () => logger
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(index_exports);
|
|
28
|
+
var import_logging = require("@google-cloud/logging");
|
|
29
|
+
function formatMessage(args) {
|
|
30
|
+
return args.map((arg) => {
|
|
31
|
+
if (typeof arg === "string") return arg;
|
|
32
|
+
if (arg instanceof Error) return arg.message + (arg.stack ? `
|
|
33
|
+
${arg.stack}` : "");
|
|
34
|
+
try {
|
|
35
|
+
return JSON.stringify(arg);
|
|
36
|
+
} catch {
|
|
37
|
+
return String(arg);
|
|
38
|
+
}
|
|
39
|
+
}).join(" ");
|
|
40
|
+
}
|
|
41
|
+
var USE_GCP = process.env.SYSTEM_LOGS === "gcp" || !!process.env.K_SERVICE;
|
|
42
|
+
var noop = () => {
|
|
43
|
+
};
|
|
44
|
+
function gcpPayload(args) {
|
|
45
|
+
const last = args[args.length - 1];
|
|
46
|
+
if (args.length >= 2 && last !== null && typeof last === "object" && !Array.isArray(last) && !(last instanceof Error)) {
|
|
47
|
+
return { message: formatMessage(args.slice(0, -1)), ...last };
|
|
48
|
+
}
|
|
49
|
+
return formatMessage(args);
|
|
50
|
+
}
|
|
51
|
+
var gcpLog = null;
|
|
52
|
+
if (USE_GCP) {
|
|
53
|
+
try {
|
|
54
|
+
const logName = process.env.K_SERVICE ?? "app";
|
|
55
|
+
gcpLog = new import_logging.Logging({ projectId: process.env.GCP_PROJECT }).log(logName);
|
|
56
|
+
} catch {
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
var logger = gcpLog ? /* @__PURE__ */ (() => {
|
|
60
|
+
const g = gcpLog;
|
|
61
|
+
return {
|
|
62
|
+
debug: (...args) => {
|
|
63
|
+
const mapped = args.map((a) => typeof a === "string" ? a.replace(/\n/g, " ") : a);
|
|
64
|
+
g.write(g.entry({ severity: "DEBUG" }, gcpPayload(mapped))).catch(noop);
|
|
65
|
+
},
|
|
66
|
+
info: (...args) => {
|
|
67
|
+
g.write(g.entry({ severity: "INFO" }, gcpPayload(args))).catch(noop);
|
|
68
|
+
},
|
|
69
|
+
notice: (...args) => {
|
|
70
|
+
g.write(g.entry({ severity: "NOTICE" }, gcpPayload(args))).catch(noop);
|
|
71
|
+
},
|
|
72
|
+
warning: (...args) => {
|
|
73
|
+
g.write(g.entry({ severity: "WARNING" }, gcpPayload(args))).catch(noop);
|
|
74
|
+
},
|
|
75
|
+
error: (...args) => {
|
|
76
|
+
g.write(g.entry({ severity: "ERROR" }, gcpPayload(args))).catch(noop);
|
|
77
|
+
},
|
|
78
|
+
critical: (...args) => {
|
|
79
|
+
g.write(g.entry({ severity: "CRITICAL" }, gcpPayload(args))).catch(noop);
|
|
80
|
+
},
|
|
81
|
+
alert: (...args) => {
|
|
82
|
+
g.write(g.entry({ severity: "ALERT" }, gcpPayload(args))).catch(noop);
|
|
83
|
+
},
|
|
84
|
+
emergency: (...args) => {
|
|
85
|
+
g.write(g.entry({ severity: "EMERGENCY" }, gcpPayload(args))).catch(noop);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
})() : {
|
|
89
|
+
debug: (...args) => {
|
|
90
|
+
console.log("[DEBUG]", ...args.map((a) => typeof a === "string" ? a.replace(/\n/g, " ") : a));
|
|
91
|
+
},
|
|
92
|
+
info: (...args) => {
|
|
93
|
+
console.log("[INFO]", ...args);
|
|
94
|
+
},
|
|
95
|
+
notice: (...args) => {
|
|
96
|
+
console.log("[NOTICE]", ...args);
|
|
97
|
+
},
|
|
98
|
+
warning: (...args) => {
|
|
99
|
+
console.log("[WARNING]", ...args);
|
|
100
|
+
},
|
|
101
|
+
error: (...args) => {
|
|
102
|
+
console.log("[ERROR]", ...args);
|
|
103
|
+
},
|
|
104
|
+
critical: (...args) => {
|
|
105
|
+
console.log("[CRITICAL]", ...args);
|
|
106
|
+
},
|
|
107
|
+
alert: (...args) => {
|
|
108
|
+
console.log("[ALERT]", ...args);
|
|
109
|
+
},
|
|
110
|
+
emergency: (...args) => {
|
|
111
|
+
console.log("[EMERGENCY]", ...args);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
var index_default = logger;
|
|
115
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
116
|
+
0 && (module.exports = {
|
|
117
|
+
formatMessage,
|
|
118
|
+
logger
|
|
119
|
+
});
|
|
120
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { Logging } from \"@google-cloud/logging\";\n\nexport interface Logger {\n debug: (...args: unknown[]) => void;\n info: (...args: unknown[]) => void;\n notice: (...args: unknown[]) => void;\n warning: (...args: unknown[]) => void;\n error: (...args: unknown[]) => void;\n critical: (...args: unknown[]) => void;\n alert: (...args: unknown[]) => void;\n emergency: (...args: unknown[]) => void;\n}\n\nexport function formatMessage(args: unknown[]): string {\n return args.map(arg => {\n if (typeof arg === \"string\") return arg;\n if (arg instanceof Error) return arg.message + (arg.stack ? `\\n${arg.stack}` : \"\");\n try {\n return JSON.stringify(arg);\n } catch {\n return String(arg);\n }\n }).join(\" \");\n}\n\n// Resolved once at module load — no per-call branching.\nconst USE_GCP = process.env.SYSTEM_LOGS === \"gcp\" || !!process.env.K_SERVICE;\nconst noop = (): void => {};\n\n// If the last arg is a plain object, return a jsonPayload so Cloud Logging\n// indexes its fields. Otherwise return a plain string (textPayload).\nfunction gcpPayload(args: unknown[]): string | Record<string, unknown> {\n const last = args[args.length - 1];\n if (\n args.length >= 2 &&\n last !== null &&\n typeof last === \"object\" &&\n !Array.isArray(last) &&\n !(last instanceof Error)\n ) {\n return { message: formatMessage(args.slice(0, -1)), ...(last as Record<string, unknown>) };\n }\n return formatMessage(args);\n}\n\nlet gcpLog: ReturnType<Logging[\"log\"]> | null = null;\nif (USE_GCP) {\n try {\n const logName = process.env.K_SERVICE ?? \"app\";\n gcpLog = new Logging({ projectId: process.env.GCP_PROJECT }).log(logName);\n } catch {\n // GCP init failed; fall back to console\n }\n}\n\nexport const logger: Logger = gcpLog\n ? (() => {\n const g = gcpLog!;\n return {\n debug: (...args: unknown[]): void => {\n const mapped = args.map(a => typeof a === \"string\" ? a.replace(/\\n/g, \" \") : a);\n g.write(g.entry({ severity: \"DEBUG\" }, gcpPayload(mapped))).catch(noop);\n },\n info: (...args: unknown[]): void => {\n g.write(g.entry({ severity: \"INFO\" }, gcpPayload(args))).catch(noop);\n },\n notice: (...args: unknown[]): void => {\n g.write(g.entry({ severity: \"NOTICE\" }, gcpPayload(args))).catch(noop);\n },\n warning: (...args: unknown[]): void => {\n g.write(g.entry({ severity: \"WARNING\" }, gcpPayload(args))).catch(noop);\n },\n error: (...args: unknown[]): void => {\n g.write(g.entry({ severity: \"ERROR\" }, gcpPayload(args))).catch(noop);\n },\n critical: (...args: unknown[]): void => {\n g.write(g.entry({ severity: \"CRITICAL\" }, gcpPayload(args))).catch(noop);\n },\n alert: (...args: unknown[]): void => {\n g.write(g.entry({ severity: \"ALERT\" }, gcpPayload(args))).catch(noop);\n },\n emergency: (...args: unknown[]): void => {\n g.write(g.entry({ severity: \"EMERGENCY\" }, gcpPayload(args))).catch(noop);\n },\n };\n })()\n : {\n debug: (...args: unknown[]): void => {\n console.log(\"[DEBUG]\", ...args.map(a => typeof a === \"string\" ? a.replace(/\\n/g, \" \") : a));\n },\n info: (...args: unknown[]): void => {\n console.log(\"[INFO]\", ...args);\n },\n notice: (...args: unknown[]): void => {\n console.log(\"[NOTICE]\", ...args);\n },\n warning: (...args: unknown[]): void => {\n console.log(\"[WARNING]\", ...args);\n },\n error: (...args: unknown[]): void => {\n console.log(\"[ERROR]\", ...args);\n },\n critical: (...args: unknown[]): void => {\n console.log(\"[CRITICAL]\", ...args);\n },\n alert: (...args: unknown[]): void => {\n console.log(\"[ALERT]\", ...args);\n },\n emergency: (...args: unknown[]): void => {\n console.log(\"[EMERGENCY]\", ...args);\n },\n };\n\nexport default logger;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAAwB;AAajB,SAAS,cAAc,MAAyB;AACrD,SAAO,KAAK,IAAI,SAAO;AACrB,QAAI,OAAO,QAAQ,SAAU,QAAO;AACpC,QAAI,eAAe,MAAO,QAAO,IAAI,WAAW,IAAI,QAAQ;AAAA,EAAK,IAAI,KAAK,KAAK;AAC/E,QAAI;AACF,aAAO,KAAK,UAAU,GAAG;AAAA,IAC3B,QAAQ;AACN,aAAO,OAAO,GAAG;AAAA,IACnB;AAAA,EACF,CAAC,EAAE,KAAK,GAAG;AACb;AAGA,IAAM,UAAU,QAAQ,IAAI,gBAAgB,SAAS,CAAC,CAAC,QAAQ,IAAI;AACnE,IAAM,OAAO,MAAY;AAAC;AAI1B,SAAS,WAAW,MAAmD;AACrE,QAAM,OAAO,KAAK,KAAK,SAAS,CAAC;AACjC,MACE,KAAK,UAAU,KACf,SAAS,QACT,OAAO,SAAS,YAChB,CAAC,MAAM,QAAQ,IAAI,KACnB,EAAE,gBAAgB,QAClB;AACA,WAAO,EAAE,SAAS,cAAc,KAAK,MAAM,GAAG,EAAE,CAAC,GAAG,GAAI,KAAiC;AAAA,EAC3F;AACA,SAAO,cAAc,IAAI;AAC3B;AAEA,IAAI,SAA4C;AAChD,IAAI,SAAS;AACX,MAAI;AACF,UAAM,UAAU,QAAQ,IAAI,aAAa;AACzC,aAAS,IAAI,uBAAQ,EAAE,WAAW,QAAQ,IAAI,YAAY,CAAC,EAAE,IAAI,OAAO;AAAA,EAC1E,QAAQ;AAAA,EAER;AACF;AAEO,IAAM,SAAiB,SACzB,uBAAM;AACL,QAAM,IAAI;AACV,SAAO;AAAA,IACL,OAAO,IAAI,SAA0B;AACnC,YAAM,SAAS,KAAK,IAAI,OAAK,OAAO,MAAM,WAAW,EAAE,QAAQ,OAAO,GAAG,IAAI,CAAC;AAC9E,QAAE,MAAM,EAAE,MAAM,EAAE,UAAU,QAAQ,GAAG,WAAW,MAAM,CAAC,CAAC,EAAE,MAAM,IAAI;AAAA,IACxE;AAAA,IACA,MAAM,IAAI,SAA0B;AAClC,QAAE,MAAM,EAAE,MAAM,EAAE,UAAU,OAAO,GAAG,WAAW,IAAI,CAAC,CAAC,EAAE,MAAM,IAAI;AAAA,IACrE;AAAA,IACA,QAAQ,IAAI,SAA0B;AACpC,QAAE,MAAM,EAAE,MAAM,EAAE,UAAU,SAAS,GAAG,WAAW,IAAI,CAAC,CAAC,EAAE,MAAM,IAAI;AAAA,IACvE;AAAA,IACA,SAAS,IAAI,SAA0B;AACrC,QAAE,MAAM,EAAE,MAAM,EAAE,UAAU,UAAU,GAAG,WAAW,IAAI,CAAC,CAAC,EAAE,MAAM,IAAI;AAAA,IACxE;AAAA,IACA,OAAO,IAAI,SAA0B;AACnC,QAAE,MAAM,EAAE,MAAM,EAAE,UAAU,QAAQ,GAAG,WAAW,IAAI,CAAC,CAAC,EAAE,MAAM,IAAI;AAAA,IACtE;AAAA,IACA,UAAU,IAAI,SAA0B;AACtC,QAAE,MAAM,EAAE,MAAM,EAAE,UAAU,WAAW,GAAG,WAAW,IAAI,CAAC,CAAC,EAAE,MAAM,IAAI;AAAA,IACzE;AAAA,IACA,OAAO,IAAI,SAA0B;AACnC,QAAE,MAAM,EAAE,MAAM,EAAE,UAAU,QAAQ,GAAG,WAAW,IAAI,CAAC,CAAC,EAAE,MAAM,IAAI;AAAA,IACtE;AAAA,IACA,WAAW,IAAI,SAA0B;AACvC,QAAE,MAAM,EAAE,MAAM,EAAE,UAAU,YAAY,GAAG,WAAW,IAAI,CAAC,CAAC,EAAE,MAAM,IAAI;AAAA,IAC1E;AAAA,EACF;AACF,GAAG,IACH;AAAA,EACE,OAAO,IAAI,SAA0B;AACnC,YAAQ,IAAI,WAAW,GAAG,KAAK,IAAI,OAAK,OAAO,MAAM,WAAW,EAAE,QAAQ,OAAO,GAAG,IAAI,CAAC,CAAC;AAAA,EAC5F;AAAA,EACA,MAAM,IAAI,SAA0B;AAClC,YAAQ,IAAI,UAAU,GAAG,IAAI;AAAA,EAC/B;AAAA,EACA,QAAQ,IAAI,SAA0B;AACpC,YAAQ,IAAI,YAAY,GAAG,IAAI;AAAA,EACjC;AAAA,EACA,SAAS,IAAI,SAA0B;AACrC,YAAQ,IAAI,aAAa,GAAG,IAAI;AAAA,EAClC;AAAA,EACA,OAAO,IAAI,SAA0B;AACnC,YAAQ,IAAI,WAAW,GAAG,IAAI;AAAA,EAChC;AAAA,EACA,UAAU,IAAI,SAA0B;AACtC,YAAQ,IAAI,cAAc,GAAG,IAAI;AAAA,EACnC;AAAA,EACA,OAAO,IAAI,SAA0B;AACnC,YAAQ,IAAI,WAAW,GAAG,IAAI;AAAA,EAChC;AAAA,EACA,WAAW,IAAI,SAA0B;AACvC,YAAQ,IAAI,eAAe,GAAG,IAAI;AAAA,EACpC;AACF;AAEJ,IAAO,gBAAQ;","names":[]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
interface Logger {
|
|
2
|
+
debug: (...args: unknown[]) => void;
|
|
3
|
+
info: (...args: unknown[]) => void;
|
|
4
|
+
notice: (...args: unknown[]) => void;
|
|
5
|
+
warning: (...args: unknown[]) => void;
|
|
6
|
+
error: (...args: unknown[]) => void;
|
|
7
|
+
critical: (...args: unknown[]) => void;
|
|
8
|
+
alert: (...args: unknown[]) => void;
|
|
9
|
+
emergency: (...args: unknown[]) => void;
|
|
10
|
+
}
|
|
11
|
+
declare function formatMessage(args: unknown[]): string;
|
|
12
|
+
declare const logger: Logger;
|
|
13
|
+
|
|
14
|
+
export { type Logger, logger as default, formatMessage, logger };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
interface Logger {
|
|
2
|
+
debug: (...args: unknown[]) => void;
|
|
3
|
+
info: (...args: unknown[]) => void;
|
|
4
|
+
notice: (...args: unknown[]) => void;
|
|
5
|
+
warning: (...args: unknown[]) => void;
|
|
6
|
+
error: (...args: unknown[]) => void;
|
|
7
|
+
critical: (...args: unknown[]) => void;
|
|
8
|
+
alert: (...args: unknown[]) => void;
|
|
9
|
+
emergency: (...args: unknown[]) => void;
|
|
10
|
+
}
|
|
11
|
+
declare function formatMessage(args: unknown[]): string;
|
|
12
|
+
declare const logger: Logger;
|
|
13
|
+
|
|
14
|
+
export { type Logger, logger as default, formatMessage, logger };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { Logging } from "@google-cloud/logging";
|
|
3
|
+
function formatMessage(args) {
|
|
4
|
+
return args.map((arg) => {
|
|
5
|
+
if (typeof arg === "string") return arg;
|
|
6
|
+
if (arg instanceof Error) return arg.message + (arg.stack ? `
|
|
7
|
+
${arg.stack}` : "");
|
|
8
|
+
try {
|
|
9
|
+
return JSON.stringify(arg);
|
|
10
|
+
} catch {
|
|
11
|
+
return String(arg);
|
|
12
|
+
}
|
|
13
|
+
}).join(" ");
|
|
14
|
+
}
|
|
15
|
+
var USE_GCP = process.env.SYSTEM_LOGS === "gcp" || !!process.env.K_SERVICE;
|
|
16
|
+
var noop = () => {
|
|
17
|
+
};
|
|
18
|
+
function gcpPayload(args) {
|
|
19
|
+
const last = args[args.length - 1];
|
|
20
|
+
if (args.length >= 2 && last !== null && typeof last === "object" && !Array.isArray(last) && !(last instanceof Error)) {
|
|
21
|
+
return { message: formatMessage(args.slice(0, -1)), ...last };
|
|
22
|
+
}
|
|
23
|
+
return formatMessage(args);
|
|
24
|
+
}
|
|
25
|
+
var gcpLog = null;
|
|
26
|
+
if (USE_GCP) {
|
|
27
|
+
try {
|
|
28
|
+
const logName = process.env.K_SERVICE ?? "app";
|
|
29
|
+
gcpLog = new Logging({ projectId: process.env.GCP_PROJECT }).log(logName);
|
|
30
|
+
} catch {
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
var logger = gcpLog ? /* @__PURE__ */ (() => {
|
|
34
|
+
const g = gcpLog;
|
|
35
|
+
return {
|
|
36
|
+
debug: (...args) => {
|
|
37
|
+
const mapped = args.map((a) => typeof a === "string" ? a.replace(/\n/g, " ") : a);
|
|
38
|
+
g.write(g.entry({ severity: "DEBUG" }, gcpPayload(mapped))).catch(noop);
|
|
39
|
+
},
|
|
40
|
+
info: (...args) => {
|
|
41
|
+
g.write(g.entry({ severity: "INFO" }, gcpPayload(args))).catch(noop);
|
|
42
|
+
},
|
|
43
|
+
notice: (...args) => {
|
|
44
|
+
g.write(g.entry({ severity: "NOTICE" }, gcpPayload(args))).catch(noop);
|
|
45
|
+
},
|
|
46
|
+
warning: (...args) => {
|
|
47
|
+
g.write(g.entry({ severity: "WARNING" }, gcpPayload(args))).catch(noop);
|
|
48
|
+
},
|
|
49
|
+
error: (...args) => {
|
|
50
|
+
g.write(g.entry({ severity: "ERROR" }, gcpPayload(args))).catch(noop);
|
|
51
|
+
},
|
|
52
|
+
critical: (...args) => {
|
|
53
|
+
g.write(g.entry({ severity: "CRITICAL" }, gcpPayload(args))).catch(noop);
|
|
54
|
+
},
|
|
55
|
+
alert: (...args) => {
|
|
56
|
+
g.write(g.entry({ severity: "ALERT" }, gcpPayload(args))).catch(noop);
|
|
57
|
+
},
|
|
58
|
+
emergency: (...args) => {
|
|
59
|
+
g.write(g.entry({ severity: "EMERGENCY" }, gcpPayload(args))).catch(noop);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
})() : {
|
|
63
|
+
debug: (...args) => {
|
|
64
|
+
console.log("[DEBUG]", ...args.map((a) => typeof a === "string" ? a.replace(/\n/g, " ") : a));
|
|
65
|
+
},
|
|
66
|
+
info: (...args) => {
|
|
67
|
+
console.log("[INFO]", ...args);
|
|
68
|
+
},
|
|
69
|
+
notice: (...args) => {
|
|
70
|
+
console.log("[NOTICE]", ...args);
|
|
71
|
+
},
|
|
72
|
+
warning: (...args) => {
|
|
73
|
+
console.log("[WARNING]", ...args);
|
|
74
|
+
},
|
|
75
|
+
error: (...args) => {
|
|
76
|
+
console.log("[ERROR]", ...args);
|
|
77
|
+
},
|
|
78
|
+
critical: (...args) => {
|
|
79
|
+
console.log("[CRITICAL]", ...args);
|
|
80
|
+
},
|
|
81
|
+
alert: (...args) => {
|
|
82
|
+
console.log("[ALERT]", ...args);
|
|
83
|
+
},
|
|
84
|
+
emergency: (...args) => {
|
|
85
|
+
console.log("[EMERGENCY]", ...args);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
var index_default = logger;
|
|
89
|
+
export {
|
|
90
|
+
index_default as default,
|
|
91
|
+
formatMessage,
|
|
92
|
+
logger
|
|
93
|
+
};
|
|
94
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { Logging } from \"@google-cloud/logging\";\n\nexport interface Logger {\n debug: (...args: unknown[]) => void;\n info: (...args: unknown[]) => void;\n notice: (...args: unknown[]) => void;\n warning: (...args: unknown[]) => void;\n error: (...args: unknown[]) => void;\n critical: (...args: unknown[]) => void;\n alert: (...args: unknown[]) => void;\n emergency: (...args: unknown[]) => void;\n}\n\nexport function formatMessage(args: unknown[]): string {\n return args.map(arg => {\n if (typeof arg === \"string\") return arg;\n if (arg instanceof Error) return arg.message + (arg.stack ? `\\n${arg.stack}` : \"\");\n try {\n return JSON.stringify(arg);\n } catch {\n return String(arg);\n }\n }).join(\" \");\n}\n\n// Resolved once at module load — no per-call branching.\nconst USE_GCP = process.env.SYSTEM_LOGS === \"gcp\" || !!process.env.K_SERVICE;\nconst noop = (): void => {};\n\n// If the last arg is a plain object, return a jsonPayload so Cloud Logging\n// indexes its fields. Otherwise return a plain string (textPayload).\nfunction gcpPayload(args: unknown[]): string | Record<string, unknown> {\n const last = args[args.length - 1];\n if (\n args.length >= 2 &&\n last !== null &&\n typeof last === \"object\" &&\n !Array.isArray(last) &&\n !(last instanceof Error)\n ) {\n return { message: formatMessage(args.slice(0, -1)), ...(last as Record<string, unknown>) };\n }\n return formatMessage(args);\n}\n\nlet gcpLog: ReturnType<Logging[\"log\"]> | null = null;\nif (USE_GCP) {\n try {\n const logName = process.env.K_SERVICE ?? \"app\";\n gcpLog = new Logging({ projectId: process.env.GCP_PROJECT }).log(logName);\n } catch {\n // GCP init failed; fall back to console\n }\n}\n\nexport const logger: Logger = gcpLog\n ? (() => {\n const g = gcpLog!;\n return {\n debug: (...args: unknown[]): void => {\n const mapped = args.map(a => typeof a === \"string\" ? a.replace(/\\n/g, \" \") : a);\n g.write(g.entry({ severity: \"DEBUG\" }, gcpPayload(mapped))).catch(noop);\n },\n info: (...args: unknown[]): void => {\n g.write(g.entry({ severity: \"INFO\" }, gcpPayload(args))).catch(noop);\n },\n notice: (...args: unknown[]): void => {\n g.write(g.entry({ severity: \"NOTICE\" }, gcpPayload(args))).catch(noop);\n },\n warning: (...args: unknown[]): void => {\n g.write(g.entry({ severity: \"WARNING\" }, gcpPayload(args))).catch(noop);\n },\n error: (...args: unknown[]): void => {\n g.write(g.entry({ severity: \"ERROR\" }, gcpPayload(args))).catch(noop);\n },\n critical: (...args: unknown[]): void => {\n g.write(g.entry({ severity: \"CRITICAL\" }, gcpPayload(args))).catch(noop);\n },\n alert: (...args: unknown[]): void => {\n g.write(g.entry({ severity: \"ALERT\" }, gcpPayload(args))).catch(noop);\n },\n emergency: (...args: unknown[]): void => {\n g.write(g.entry({ severity: \"EMERGENCY\" }, gcpPayload(args))).catch(noop);\n },\n };\n })()\n : {\n debug: (...args: unknown[]): void => {\n console.log(\"[DEBUG]\", ...args.map(a => typeof a === \"string\" ? a.replace(/\\n/g, \" \") : a));\n },\n info: (...args: unknown[]): void => {\n console.log(\"[INFO]\", ...args);\n },\n notice: (...args: unknown[]): void => {\n console.log(\"[NOTICE]\", ...args);\n },\n warning: (...args: unknown[]): void => {\n console.log(\"[WARNING]\", ...args);\n },\n error: (...args: unknown[]): void => {\n console.log(\"[ERROR]\", ...args);\n },\n critical: (...args: unknown[]): void => {\n console.log(\"[CRITICAL]\", ...args);\n },\n alert: (...args: unknown[]): void => {\n console.log(\"[ALERT]\", ...args);\n },\n emergency: (...args: unknown[]): void => {\n console.log(\"[EMERGENCY]\", ...args);\n },\n };\n\nexport default logger;\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@logickernel/logger",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "dist/index.cjs",
|
|
6
|
+
"module": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"require": "./dist/index.cjs"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsup",
|
|
20
|
+
"dev": "tsup --watch",
|
|
21
|
+
"typecheck": "tsc --noEmit",
|
|
22
|
+
"test": "vitest run src/index.test.ts",
|
|
23
|
+
"test:integration": "vitest run src/index.integration.test.ts",
|
|
24
|
+
"test:watch": "vitest"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@google-cloud/logging": "^11"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"tsup": "^8",
|
|
31
|
+
"typescript": "^5",
|
|
32
|
+
"vitest": "^3"
|
|
33
|
+
}
|
|
34
|
+
}
|