@logickernel/logger 0.7.0 → 0.9.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 CHANGED
@@ -3,12 +3,13 @@
3
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
4
 
5
5
  ```ts
6
- import logger from "@logickernel/logger";
6
+ import { logger } from "@logickernel/logger";
7
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" });
8
+ const log = logger("api"); // optional scope label on every entry
9
+
10
+ log.info("server started", { port: 3000 });
11
+ log.debug("user action", { userId: "123", action: "login" });
12
+ log.warning("disk space low", { used: "92%", mount: "/data" });
12
13
  ```
13
14
 
14
15
  > Your code never has to care whether it's running on Cloud Run / GCP or locally – the logger picks the right backend at startup.
@@ -18,10 +19,10 @@ logger.warning("disk space low", { used: "92%", mount: "/data" });
18
19
  ## 1. Introduction
19
20
 
20
21
  - **What it is**: A tiny logging helper with the full GCP severity ladder and a configurable backend:
21
- - In **GCP** (or when `LOGGER_TARGET=gcp`): writes to Google Cloud Logging with proper severities and structured `jsonPayload` when a context object is provided.
22
- - On the **console**: writes with emoji prefixes, a local timestamp, and the context object inlined as compact JSON.
22
+ - In **GCP** (or when `LOGGER_TARGET=gcp`): writes to Google Cloud Logging with proper severities and structured `jsonPayload` when a payload object is provided.
23
+ - On the **console**: writes with emoji prefixes, a local timestamp, and the payload inlined as compact JSON.
23
24
  - **Both at once**: set `LOGGER_TARGET=gcp,console` to fan out to both.
24
- - **Why it exists**: To avoid sprinkling environment-specific logging logic across your codebase. You import one `logger` and use it everywhere.
25
+ - **Why it exists**: To avoid sprinkling environment-specific logging logic across your codebase. You import one factory and use it everywhere.
25
26
 
26
27
  **Key features**
27
28
 
@@ -29,8 +30,9 @@ logger.warning("disk space low", { used: "92%", mount: "/data" });
29
30
  - **Auto backend selection**: GCP vs console decided once at module load; override with `LOGGER_TARGET`.
30
31
  - **Multi-backend**: `LOGGER_TARGET` accepts a comma-separated list — `"gcp,console"` writes to both simultaneously.
31
32
  - **Full severity ladder**: `debug`, `info`, `notice`, `warning`, `error`, `critical`, `alert`, `emergency`.
32
- - **Structured context**: Pass a plain object as the last argument — it becomes a `jsonPayload` in GCP (queryable by field) and inline JSON in the console.
33
- - **Tiny API**: One default export (`logger`) plus a `formatMessage` helper if you need it.
33
+ - **Structured context**: Pass a plain object as the second argument — it becomes a `jsonPayload` in GCP (queryable by field) and inline JSON in the console.
34
+ - **Scope**: `logger("name")` attaches a `scope` label to every entry, great for filtering by component.
35
+ - **Per-call labels**: Pass a third argument to attach GCP labels to a single entry (e.g. `traceId`, `userId`).
34
36
 
35
37
  ---
36
38
 
@@ -45,26 +47,42 @@ npm install @logickernel/logger
45
47
  ### Basic usage
46
48
 
47
49
  ```ts
48
- import logger from "@logickernel/logger";
49
-
50
- // Message only
51
- logger.info("server started");
52
- logger.debug("cache miss");
53
- logger.error(new Error("connection refused"));
54
-
55
- // Message with structured context
56
- logger.info("server started", { port: 3000, env: "production" });
57
- logger.debug("cache miss", { key: "user:42", ttl: 300 });
58
- logger.warning("disk space low", { used: "92%", mount: "/data" });
59
- logger.error("request failed", { method: "POST", path: "/api/orders", status: 503 });
60
- logger.critical("primary db unreachable", { host: "db-1", retries: 3 });
50
+ import { logger } from "@logickernel/logger";
51
+
52
+ // Scopeless logger — fine for scripts and simple tools
53
+ const log = logger();
54
+
55
+ log.info("server started");
56
+ log.debug("cache miss");
57
+ log.warning("disk space low", { used: "92%", mount: "/data" });
58
+ log.error("request failed", { method: "POST", path: "/api/orders", status: 503 });
59
+ log.critical("primary db unreachable", { host: "db-1", retries: 3 });
60
+
61
+ // Scoped logger attaches scope: "api" to every entry as a GCP label
62
+ const apiLog = logger("api");
63
+ apiLog.info("request handled", { method: "GET", status: 200 });
64
+
65
+ // Per-call labels — merged with scope and env labels for that entry only
66
+ apiLog.info("request handled", { method: "GET", status: 200 }, { traceId: "abc-123" });
61
67
  ```
62
68
 
63
- The default export is a **singleton** whose backend is chosen at module load:
69
+ `logger(scope?)` returns a `Logger` instance. Call it once per module or service boundary. The backend (GCP or console) is chosen once at module load:
64
70
 
65
71
  - **GCP backend** is used when `GCP_PROJECT` is set.
66
72
  - Otherwise, the **console backend** is used.
67
73
 
74
+ ### Method signature
75
+
76
+ All eight severity methods share the same signature:
77
+
78
+ ```ts
79
+ log.info(message: string, payload?: Record<string, unknown>, labels?: Record<string, string>): void
80
+ ```
81
+
82
+ - **`message`** — required string.
83
+ - **`payload`** — optional plain object. Becomes `jsonPayload` in GCP (fields indexed and queryable); inlined as compact JSON on the console.
84
+ - **`labels`** — optional per-call labels merged with scope and env labels (GCP only; ignored on console).
85
+
68
86
  ### Severity methods
69
87
 
70
88
  | Method | GCP severity | Console emoji |
@@ -78,57 +96,95 @@ The default export is a **singleton** whose backend is chosen at module load:
78
96
  | `alert` | `ALERT` | ❗️ |
79
97
  | `emergency` | `EMERGENCY` | 🚨 |
80
98
 
99
+ ### Scope
100
+
101
+ `logger(scope)` attaches a `scope` label to every entry, letting you filter by component in Cloud Logging:
102
+
103
+ ```ts
104
+ const db = logger("db");
105
+ db.warning("slow query", { ms: 412, query: "SELECT ..." });
106
+ // GCP entry: labels.scope = "db"
107
+ ```
108
+
81
109
  ### Structured context
82
110
 
83
- Pass a plain object as the last argument to attach structured data to a log entry:
111
+ Pass a plain object as the second argument to attach structured data to a log entry:
84
112
 
85
113
  ```ts
86
- logger.info("request complete", { method: "GET", path: "/api/users", status: 200, ms: 42 });
114
+ log.info("request complete", { method: "GET", path: "/api/users", status: 200, ms: 42 });
87
115
  ```
88
116
 
89
117
  - **GCP backend**: written as `jsonPayload` — fields are indexed and queryable in Cloud Logging.
90
118
  - **Console backend**: inlined as spaced JSON on the same line.
91
119
 
120
+ ### Per-call labels
121
+
122
+ Pass a `Record<string, string>` as the third argument to attach labels to a single entry (GCP only). They are merged with env labels and scope, with per-call values taking precedence:
123
+
124
+ ```ts
125
+ log.info("payment processed", { amount: 99 }, { traceId: "t-123", userId: "u-42" });
126
+ // GCP entry: labels = { ...envLabels, scope: "...", traceId: "t-123", userId: "u-42" }
127
+ ```
128
+
92
129
  ### Console format
93
130
 
94
- By default, console logs are plain: `message [payload]` without emoji or timestamp.
131
+ By default, console logs are plain: `[(scope) ]message[ {payload}]` without emoji or timestamp.
95
132
 
96
133
  When `LOGGER_CONSOLE_FORMAT=pretty`, console logs look like:
97
134
 
98
135
  ```
99
136
  ⚪️ 2026-02-26 13:04:22.120 server started
100
- 🐞 2026-02-26 13:04:22.341 cache miss { "key": "user:42", "ttl": 300 }
101
- 🟡 2026-02-26 13:04:22.512 disk space low { "used": "92%", "mount": "/data" }
137
+ 🐞 2026-02-26 13:04:22.341 (api) cache miss
138
+ {
139
+ "key": "user:42",
140
+ "ttl": 300
141
+ }
142
+ 🟡 2026-02-26 13:04:22.512 disk space low
143
+ {
144
+ "used": "92%",
145
+ "mount": "/data"
146
+ }
102
147
  ```
103
148
 
104
- This "pretty" format (emoji + local timestamp + message + optional payload) is meant to roughly emulate what you see in the GCP Logging console when browsing entries by severity and time.
149
+ Scope (if set) appears in parentheses before the message. Payload (if any) is printed on the next line with 4-space indentation. Labels are GCP metadata and are not shown on the console.
105
150
 
106
151
  ### Environment variables
107
152
 
108
- - `GCP_PROJECT`
109
- Project ID for Google Cloud Logging. When set (and `LOGGER_TARGET` isn’t forcing console), the GCP backend is used.
153
+ - `LOGGER_NAME`
154
+ Log name in Google Cloud Logging. This is a very important attribute that is the primary group in reports — logs are usually grouped by system instance/environment so entries stay together. Falls back to `K_SERVICE`, then `"local"`.
110
155
 
111
- - `LOGGER_NAME`
112
- Log name in Google Cloud Logging. Falls back to `K_SERVICE`, then `"local"`.
156
+ - `GCP_PROJECT`
157
+ Project ID for Google Cloud Logging. When set (and `LOGGER_TARGET` isn't forcing console), the GCP backend is used.
113
158
 
114
159
  - `LOGGER_TARGET`
115
160
  Comma-separated list of backends to activate: `"gcp"`, `"console"`, or `"gcp,console"` for both simultaneously. When unset, GCP is used if `GCP_PROJECT` is set, otherwise console.
116
161
 
117
162
  - `LOGGER_CONSOLE_FORMAT`
118
- Controls the console output format. When set to `"pretty"`, uses emoji + timestamp lines (mirroring the feel of GCP Logging's console UI); otherwise (default) prints plain `message [payload]` without emoji or timestamp.
163
+ Controls the console output format. When set to `"pretty"`, uses emoji + timestamp lines to emulate GCP's log viewer; otherwise (default) prints plain `message [payload]` without emoji or timestamp.
164
+
165
+ - `ENVIRONMENT`
166
+ Attached as `labels.environment` on every GCP entry. Useful for filtering by `"production"`, `"staging"`, etc.
119
167
 
120
- - `K_SERVICE`
121
- Fallback log name in Google Cloud Logging when `LOGGER_NAME` is not set. Usually set up by Google Cloud Run. If neither is set, `"local"` is used.
168
+ - `SERVICE_ID`
169
+ Attached as `labels.service_id` on every GCP entry.
170
+
171
+ - `VERSION`
172
+ Attached as `labels.version` on every GCP entry.
173
+
174
+ - `K_SERVICE`
175
+ Fallback log name in Google Cloud Logging when `LOGGER_NAME` is not set. Usually set automatically by Google Cloud Run.
122
176
 
123
177
  ### Named exports
124
178
 
125
179
  ```ts
126
- import logger, { Logger, formatMessage } from "@logickernel/logger";
180
+ import { logger } from "@logickernel/logger";
181
+ import type { Logger } from "@logickernel/logger";
127
182
 
128
- const myLogger: Logger = logger;
129
- const message = formatMessage(["hello", { id: 1 }]); // "hello {"id":1}"
183
+ const log: Logger = logger("my-scope");
130
184
  ```
131
185
 
186
+ `logger` is also the default export: `import logger from "@logickernel/logger"`.
187
+
132
188
  ---
133
189
 
134
190
  ## 3. Local Setup (Development)
package/dist/index.cjs CHANGED
@@ -21,23 +21,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
23
  default: () => index_default,
24
- formatMessage: () => formatMessage,
25
24
  logger: () => logger
26
25
  });
27
26
  module.exports = __toCommonJS(index_exports);
28
27
  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
28
  var rawTargets = process.env.LOGGER_TARGET;
42
29
  var targets = rawTargets ? new Set(rawTargets.toLowerCase().split(",").map((s) => s.trim()).filter(Boolean)) : null;
43
30
  var USE_GCP = targets ? targets.has("gcp") : !!process.env.GCP_PROJECT;
@@ -45,151 +32,159 @@ var USE_CONSOLE = targets ? targets.has("console") : !process.env.GCP_PROJECT;
45
32
  var CONSOLE_PRETTY = process.env.LOGGER_CONSOLE_FORMAT?.toLowerCase() === "pretty";
46
33
  var noop = () => {
47
34
  };
48
- var gcpLabels = {};
49
- if (process.env.ENVIRONMENT) gcpLabels.environment = process.env.ENVIRONMENT;
50
- if (process.env.SERVICE_ID) gcpLabels.service_id = process.env.SERVICE_ID;
51
- if (process.env.VERSION) gcpLabels.version = process.env.VERSION;
52
- var GCP_ENV_LABEL = Object.keys(gcpLabels).length ? { labels: gcpLabels } : {};
53
- function consoleLine(emoji, args) {
35
+ var envLabels = {};
36
+ if (process.env.ENVIRONMENT) envLabels.environment = process.env.ENVIRONMENT;
37
+ if (process.env.SERVICE_ID) envLabels.service_id = process.env.SERVICE_ID;
38
+ if (process.env.VERSION) envLabels.version = process.env.VERSION;
39
+ var gcpLog = USE_GCP ? (() => {
40
+ try {
41
+ const logName = process.env.LOGGER_NAME ?? process.env.K_SERVICE ?? "local";
42
+ return new import_logging.Logging({ projectId: process.env.GCP_PROJECT }).log(logName);
43
+ } catch {
44
+ return null;
45
+ }
46
+ })() : null;
47
+ function consoleLine(emoji, message, payload, scope) {
54
48
  const d = /* @__PURE__ */ new Date();
55
49
  const ts = d.toLocaleString("sv-SE") + "." + String(d.getMilliseconds()).padStart(3, "0");
56
- const last = args[args.length - 1];
57
- const hasPayload = args.length >= 2 && last !== null && typeof last === "object" && !Array.isArray(last) && !(last instanceof Error);
58
- const msg = formatMessage(hasPayload ? args.slice(0, -1) : args);
59
- const suffix = hasPayload ? " " + JSON.stringify(last, null, 2).replace(/\n\s*/g, " ") : "";
60
- return `${emoji} ${ts} ${msg}${suffix}`;
50
+ const scopePart = scope ? `(${scope}) ` : "";
51
+ const suffix = payload ? "\n" + JSON.stringify(payload, null, 2).replace(/^/gm, " ") : "";
52
+ return `${emoji} ${ts} ${scopePart}${message}${suffix}`;
61
53
  }
62
- function consolePlain(args) {
63
- const last = args[args.length - 1];
64
- const hasPayload = args.length >= 2 && last !== null && typeof last === "object" && !Array.isArray(last) && !(last instanceof Error);
65
- const msg = formatMessage(hasPayload ? args.slice(0, -1) : args);
66
- const suffix = hasPayload ? " " + JSON.stringify(last, null, 2).replace(/\n\s*/g, " ") : "";
67
- return `${msg}${suffix}`;
54
+ function consolePlain(message, payload, scope) {
55
+ const scopePart = scope ? `(${scope}) ` : "";
56
+ const suffix = payload ? " " + JSON.stringify(payload, null, 2).replace(/\n\s*/g, " ") : "";
57
+ return `${scopePart}${message}${suffix}`;
68
58
  }
69
- function gcpPayload(args) {
70
- const last = args[args.length - 1];
71
- if (args.length >= 2 && last !== null && typeof last === "object" && !Array.isArray(last) && !(last instanceof Error)) {
72
- return { message: formatMessage(args.slice(0, -1)), ...last };
59
+ function logger(scope) {
60
+ const instanceLabels = {
61
+ ...envLabels,
62
+ ...scope ? { scope } : {}
63
+ };
64
+ function resolveLabels(callLabels) {
65
+ const merged = { ...instanceLabels, ...callLabels };
66
+ return Object.keys(merged).length ? merged : void 0;
73
67
  }
74
- return formatMessage(args);
75
- }
76
- var backends = [];
77
- if (USE_GCP) {
78
- try {
79
- const logName = process.env.LOGGER_NAME ?? process.env.K_SERVICE ?? "local";
80
- const g = new import_logging.Logging({ projectId: process.env.GCP_PROJECT }).log(logName);
68
+ function gcpMeta(severity, callLabels) {
69
+ const labels = resolveLabels(callLabels);
70
+ return labels ? { severity, labels } : { severity };
71
+ }
72
+ function gcpData(message, payload) {
73
+ return payload ? { message, ...payload } : message;
74
+ }
75
+ const backends = [];
76
+ if (gcpLog) {
77
+ const g = gcpLog;
81
78
  backends.push({
82
- debug: (...args) => {
83
- g.write(g.entry({ severity: "DEBUG", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop);
79
+ debug: (message, payload, labels) => {
80
+ g.write(g.entry(gcpMeta("DEBUG", labels), gcpData(message, payload))).catch(noop);
84
81
  },
85
- info: (...args) => {
86
- g.write(g.entry({ severity: "INFO", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop);
82
+ info: (message, payload, labels) => {
83
+ g.write(g.entry(gcpMeta("INFO", labels), gcpData(message, payload))).catch(noop);
87
84
  },
88
- notice: (...args) => {
89
- g.write(g.entry({ severity: "NOTICE", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop);
85
+ notice: (message, payload, labels) => {
86
+ g.write(g.entry(gcpMeta("NOTICE", labels), gcpData(message, payload))).catch(noop);
90
87
  },
91
- warning: (...args) => {
92
- g.write(g.entry({ severity: "WARNING", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop);
88
+ warning: (message, payload, labels) => {
89
+ g.write(g.entry(gcpMeta("WARNING", labels), gcpData(message, payload))).catch(noop);
93
90
  },
94
- error: (...args) => {
95
- g.write(g.entry({ severity: "ERROR", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop);
91
+ error: (message, payload, labels) => {
92
+ g.write(g.entry(gcpMeta("ERROR", labels), gcpData(message, payload))).catch(noop);
96
93
  },
97
- critical: (...args) => {
98
- g.write(g.entry({ severity: "CRITICAL", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop);
94
+ critical: (message, payload, labels) => {
95
+ g.write(g.entry(gcpMeta("CRITICAL", labels), gcpData(message, payload))).catch(noop);
99
96
  },
100
- alert: (...args) => {
101
- g.write(g.entry({ severity: "ALERT", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop);
97
+ alert: (message, payload, labels) => {
98
+ g.write(g.entry(gcpMeta("ALERT", labels), gcpData(message, payload))).catch(noop);
102
99
  },
103
- emergency: (...args) => {
104
- g.write(g.entry({ severity: "EMERGENCY", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop);
100
+ emergency: (message, payload, labels) => {
101
+ g.write(g.entry(gcpMeta("EMERGENCY", labels), gcpData(message, payload))).catch(noop);
105
102
  }
106
103
  });
107
- } catch {
108
104
  }
109
- }
110
- if (USE_CONSOLE || backends.length === 0) {
111
- backends.push(CONSOLE_PRETTY ? {
112
- debug: (...args) => {
113
- console.log(consoleLine("\u{1F41E}", args));
114
- },
115
- info: (...args) => {
116
- console.log(consoleLine("\u26AA\uFE0F", args));
117
- },
118
- notice: (...args) => {
119
- console.log(consoleLine("\u{1F535}", args));
120
- },
121
- warning: (...args) => {
122
- console.log(consoleLine("\u{1F7E1}", args));
123
- },
124
- error: (...args) => {
125
- console.log(consoleLine("\u{1F534}", args));
126
- },
127
- critical: (...args) => {
128
- console.log(consoleLine("\u26D4\uFE0F", args));
129
- },
130
- alert: (...args) => {
131
- console.log(consoleLine("\u2757\uFE0F", args));
132
- },
133
- emergency: (...args) => {
134
- console.log(consoleLine("\u{1F6A8}", args));
135
- }
136
- } : {
137
- debug: (...args) => {
138
- console.log(consolePlain(args));
105
+ if (USE_CONSOLE || backends.length === 0) {
106
+ backends.push(CONSOLE_PRETTY ? {
107
+ debug: (message, payload) => {
108
+ console.log(consoleLine("\u{1F41E}", message, payload, scope));
109
+ },
110
+ info: (message, payload) => {
111
+ console.log(consoleLine("\u26AA\uFE0F", message, payload, scope));
112
+ },
113
+ notice: (message, payload) => {
114
+ console.log(consoleLine("\u{1F535}", message, payload, scope));
115
+ },
116
+ warning: (message, payload) => {
117
+ console.log(consoleLine("\u{1F7E1}", message, payload, scope));
118
+ },
119
+ error: (message, payload) => {
120
+ console.log(consoleLine("\u{1F534}", message, payload, scope));
121
+ },
122
+ critical: (message, payload) => {
123
+ console.log(consoleLine("\u26D4\uFE0F", message, payload, scope));
124
+ },
125
+ alert: (message, payload) => {
126
+ console.log(consoleLine("\u2757\uFE0F", message, payload, scope));
127
+ },
128
+ emergency: (message, payload) => {
129
+ console.log(consoleLine("\u{1F6A8}", message, payload, scope));
130
+ }
131
+ } : {
132
+ debug: (message, payload) => {
133
+ console.log(consolePlain(message, payload, scope));
134
+ },
135
+ info: (message, payload) => {
136
+ console.log(consolePlain(message, payload, scope));
137
+ },
138
+ notice: (message, payload) => {
139
+ console.log(consolePlain(message, payload, scope));
140
+ },
141
+ warning: (message, payload) => {
142
+ console.log(consolePlain(message, payload, scope));
143
+ },
144
+ error: (message, payload) => {
145
+ console.log(consolePlain(message, payload, scope));
146
+ },
147
+ critical: (message, payload) => {
148
+ console.log(consolePlain(message, payload, scope));
149
+ },
150
+ alert: (message, payload) => {
151
+ console.log(consolePlain(message, payload, scope));
152
+ },
153
+ emergency: (message, payload) => {
154
+ console.log(consolePlain(message, payload, scope));
155
+ }
156
+ });
157
+ }
158
+ return backends.length === 1 ? backends[0] : {
159
+ debug: (message, payload, labels) => {
160
+ backends.forEach((b) => b.debug(message, payload, labels));
139
161
  },
140
- info: (...args) => {
141
- console.log(consolePlain(args));
162
+ info: (message, payload, labels) => {
163
+ backends.forEach((b) => b.info(message, payload, labels));
142
164
  },
143
- notice: (...args) => {
144
- console.log(consolePlain(args));
165
+ notice: (message, payload, labels) => {
166
+ backends.forEach((b) => b.notice(message, payload, labels));
145
167
  },
146
- warning: (...args) => {
147
- console.log(consolePlain(args));
168
+ warning: (message, payload, labels) => {
169
+ backends.forEach((b) => b.warning(message, payload, labels));
148
170
  },
149
- error: (...args) => {
150
- console.log(consolePlain(args));
171
+ error: (message, payload, labels) => {
172
+ backends.forEach((b) => b.error(message, payload, labels));
151
173
  },
152
- critical: (...args) => {
153
- console.log(consolePlain(args));
174
+ critical: (message, payload, labels) => {
175
+ backends.forEach((b) => b.critical(message, payload, labels));
154
176
  },
155
- alert: (...args) => {
156
- console.log(consolePlain(args));
177
+ alert: (message, payload, labels) => {
178
+ backends.forEach((b) => b.alert(message, payload, labels));
157
179
  },
158
- emergency: (...args) => {
159
- console.log(consolePlain(args));
180
+ emergency: (message, payload, labels) => {
181
+ backends.forEach((b) => b.emergency(message, payload, labels));
160
182
  }
161
- });
183
+ };
162
184
  }
163
- var logger = backends.length === 1 ? backends[0] : {
164
- debug: (...args) => {
165
- backends.forEach((b) => b.debug(...args));
166
- },
167
- info: (...args) => {
168
- backends.forEach((b) => b.info(...args));
169
- },
170
- notice: (...args) => {
171
- backends.forEach((b) => b.notice(...args));
172
- },
173
- warning: (...args) => {
174
- backends.forEach((b) => b.warning(...args));
175
- },
176
- error: (...args) => {
177
- backends.forEach((b) => b.error(...args));
178
- },
179
- critical: (...args) => {
180
- backends.forEach((b) => b.critical(...args));
181
- },
182
- alert: (...args) => {
183
- backends.forEach((b) => b.alert(...args));
184
- },
185
- emergency: (...args) => {
186
- backends.forEach((b) => b.emergency(...args));
187
- }
188
- };
189
185
  var index_default = logger;
190
186
  // Annotate the CommonJS export names for ESM import in node:
191
187
  0 && (module.exports = {
192
- formatMessage,
193
188
  logger
194
189
  });
195
190
  //# sourceMappingURL=index.cjs.map
@@ -1 +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.\n// LOGGER_TARGET accepts a comma-separated list of backends: \"gcp\", \"console\", or \"gcp,console\".\nconst rawTargets = process.env.LOGGER_TARGET;\nconst targets = rawTargets\n ? new Set(rawTargets.toLowerCase().split(\",\").map(s => s.trim()).filter(Boolean))\n : null;\n\nconst USE_GCP = targets ? targets.has(\"gcp\") : !!process.env.GCP_PROJECT;\nconst USE_CONSOLE = targets ? targets.has(\"console\") : !process.env.GCP_PROJECT;\nconst CONSOLE_PRETTY = process.env.LOGGER_CONSOLE_FORMAT?.toLowerCase() === \"pretty\";\nconst noop = (): void => {};\nconst gcpLabels: Record<string, string> = {};\nif (process.env.ENVIRONMENT) gcpLabels.environment = process.env.ENVIRONMENT;\nif (process.env.SERVICE_ID) gcpLabels.service_id = process.env.SERVICE_ID;\nif (process.env.VERSION) gcpLabels.version = process.env.VERSION;\nconst GCP_ENV_LABEL = Object.keys(gcpLabels).length ? { labels: gcpLabels } : {};\n\n// Formats a single console log line: \"{emoji} {local timestamp} {message} [{payload}]\"\nfunction consoleLine(emoji: string, args: unknown[]): string {\n const d = new Date();\n const ts = d.toLocaleString(\"sv-SE\") + \".\" + String(d.getMilliseconds()).padStart(3, \"0\");\n const last = args[args.length - 1];\n const hasPayload = args.length >= 2 && last !== null && typeof last === \"object\" && !Array.isArray(last) && !(last instanceof Error);\n const msg = formatMessage(hasPayload ? args.slice(0, -1) : args);\n const suffix = hasPayload ? \" \" + JSON.stringify(last, null, 2).replace(/\\n\\s*/g, \" \") : \"\";\n return `${emoji} ${ts} ${msg}${suffix}`;\n}\n\n// Plain console line: \"message [{payload}]\"\nfunction consolePlain(args: unknown[]): string {\n const last = args[args.length - 1];\n const hasPayload =\n args.length >= 2 &&\n last !== null &&\n typeof last === \"object\" &&\n !Array.isArray(last) &&\n !(last instanceof Error);\n const msg = formatMessage(hasPayload ? args.slice(0, -1) : args);\n const suffix = hasPayload ? \" \" + JSON.stringify(last, null, 2).replace(/\\n\\s*/g, \" \") : \"\";\n return `${msg}${suffix}`;\n}\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\nconst backends: Logger[] = [];\n\nif (USE_GCP) {\n try {\n const logName = process.env.LOGGER_NAME ?? process.env.K_SERVICE ?? \"local\";\n const g = new Logging({ projectId: process.env.GCP_PROJECT }).log(logName);\n backends.push({\n debug: (...args: unknown[]): void => { g.write(g.entry({ severity: \"DEBUG\", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop); },\n info: (...args: unknown[]): void => { g.write(g.entry({ severity: \"INFO\", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop); },\n notice: (...args: unknown[]): void => { g.write(g.entry({ severity: \"NOTICE\", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop); },\n warning: (...args: unknown[]): void => { g.write(g.entry({ severity: \"WARNING\", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop); },\n error: (...args: unknown[]): void => { g.write(g.entry({ severity: \"ERROR\", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop); },\n critical: (...args: unknown[]): void => { g.write(g.entry({ severity: \"CRITICAL\", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop); },\n alert: (...args: unknown[]): void => { g.write(g.entry({ severity: \"ALERT\", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop); },\n emergency: (...args: unknown[]): void => { g.write(g.entry({ severity: \"EMERGENCY\", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop); },\n });\n } catch {\n // GCP init failed; will fall back to console\n }\n}\n\nif (USE_CONSOLE || backends.length === 0) {\n backends.push(CONSOLE_PRETTY\n ? {\n debug: (...args: unknown[]): void => { console.log(consoleLine(\"🐞\", args)); },\n info: (...args: unknown[]): void => { console.log(consoleLine(\"⚪️\", args)); },\n notice: (...args: unknown[]): void => { console.log(consoleLine(\"🔵\", args)); },\n warning: (...args: unknown[]): void => { console.log(consoleLine(\"🟡\", args)); },\n error: (...args: unknown[]): void => { console.log(consoleLine(\"🔴\", args)); },\n critical: (...args: unknown[]): void => { console.log(consoleLine(\"⛔️\", args)); },\n alert: (...args: unknown[]): void => { console.log(consoleLine(\"❗️\", args)); },\n emergency: (...args: unknown[]): void => { console.log(consoleLine(\"🚨\", args)); },\n }\n : {\n debug: (...args: unknown[]): void => { console.log(consolePlain(args)); },\n info: (...args: unknown[]): void => { console.log(consolePlain(args)); },\n notice: (...args: unknown[]): void => { console.log(consolePlain(args)); },\n warning: (...args: unknown[]): void => { console.log(consolePlain(args)); },\n error: (...args: unknown[]): void => { console.log(consolePlain(args)); },\n critical: (...args: unknown[]): void => { console.log(consolePlain(args)); },\n alert: (...args: unknown[]): void => { console.log(consolePlain(args)); },\n emergency: (...args: unknown[]): void => { console.log(consolePlain(args)); },\n });\n}\n\nexport const logger: Logger =\n backends.length === 1\n ? backends[0]\n : {\n debug: (...args: unknown[]): void => { backends.forEach(b => b.debug(...args)); },\n info: (...args: unknown[]): void => { backends.forEach(b => b.info(...args)); },\n notice: (...args: unknown[]): void => { backends.forEach(b => b.notice(...args)); },\n warning: (...args: unknown[]): void => { backends.forEach(b => b.warning(...args)); },\n error: (...args: unknown[]): void => { backends.forEach(b => b.error(...args)); },\n critical: (...args: unknown[]): void => { backends.forEach(b => b.critical(...args)); },\n alert: (...args: unknown[]): void => { backends.forEach(b => b.alert(...args)); },\n emergency: (...args: unknown[]): void => { backends.forEach(b => b.emergency(...args)); },\n };\n\nexport default logger;\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { Logging } from \"@google-cloud/logging\";\n\ntype LogMethod = (message: string, payload?: Record<string, unknown>, labels?: Record<string, string>) => void;\n\nexport interface Logger {\n debug: LogMethod;\n info: LogMethod;\n notice: LogMethod;\n warning: LogMethod;\n error: LogMethod;\n critical: LogMethod;\n alert: LogMethod;\n emergency: LogMethod;\n}\n\n// Resolved once at module load — no per-call branching.\n// LOGGER_TARGET accepts a comma-separated list of backends: \"gcp\", \"console\", or \"gcp,console\".\nconst rawTargets = process.env.LOGGER_TARGET;\nconst targets = rawTargets\n ? new Set(rawTargets.toLowerCase().split(\",\").map(s => s.trim()).filter(Boolean))\n : null;\n\nconst USE_GCP = targets ? targets.has(\"gcp\") : !!process.env.GCP_PROJECT;\nconst USE_CONSOLE = targets ? targets.has(\"console\") : !process.env.GCP_PROJECT;\nconst CONSOLE_PRETTY = process.env.LOGGER_CONSOLE_FORMAT?.toLowerCase() === \"pretty\";\nconst noop = (): void => {};\n\nconst envLabels: Record<string, string> = {};\nif (process.env.ENVIRONMENT) envLabels.environment = process.env.ENVIRONMENT;\nif (process.env.SERVICE_ID) envLabels.service_id = process.env.SERVICE_ID;\nif (process.env.VERSION) envLabels.version = process.env.VERSION;\n\n// GCP Log singleton — shared across all logger() calls.\nconst gcpLog = USE_GCP ? (() => {\n try {\n const logName = process.env.LOGGER_NAME ?? process.env.K_SERVICE ?? \"local\";\n return new Logging({ projectId: process.env.GCP_PROJECT }).log(logName);\n } catch {\n return null;\n }\n})() : null;\n\n// Formats a pretty console log line: \"{emoji} {local timestamp} [(scope) ]{message}[\\n {payload}]\"\nfunction consoleLine(emoji: string, message: string, payload?: Record<string, unknown>, scope?: string): string {\n const d = new Date();\n const ts = d.toLocaleString(\"sv-SE\") + \".\" + String(d.getMilliseconds()).padStart(3, \"0\");\n const scopePart = scope ? `(${scope}) ` : \"\";\n const suffix = payload ? \"\\n\" + JSON.stringify(payload, null, 2).replace(/^/gm, \" \") : \"\";\n return `${emoji} ${ts} ${scopePart}${message}${suffix}`;\n}\n\n// Plain console line: \"[(scope) ]{message}[ {payload}]\"\nfunction consolePlain(message: string, payload?: Record<string, unknown>, scope?: string): string {\n const scopePart = scope ? `(${scope}) ` : \"\";\n const suffix = payload ? \" \" + JSON.stringify(payload, null, 2).replace(/\\n\\s*/g, \" \") : \"\";\n return `${scopePart}${message}${suffix}`;\n}\n\nexport function logger(scope?: string): Logger {\n const instanceLabels: Record<string, string> = {\n ...envLabels,\n ...(scope ? { scope } : {}),\n };\n\n function resolveLabels(callLabels?: Record<string, string>): Record<string, string> | undefined {\n const merged = { ...instanceLabels, ...callLabels };\n return Object.keys(merged).length ? merged : undefined;\n }\n\n function gcpMeta(severity: string, callLabels?: Record<string, string>): Record<string, unknown> {\n const labels = resolveLabels(callLabels);\n return labels ? { severity, labels } : { severity };\n }\n\n function gcpData(message: string, payload?: Record<string, unknown>): string | Record<string, unknown> {\n return payload ? { message, ...payload } : message;\n }\n\n const backends: Logger[] = [];\n\n if (gcpLog) {\n const g = gcpLog;\n backends.push({\n debug: (message, payload, labels): void => { g.write(g.entry(gcpMeta(\"DEBUG\", labels), gcpData(message, payload))).catch(noop); },\n info: (message, payload, labels): void => { g.write(g.entry(gcpMeta(\"INFO\", labels), gcpData(message, payload))).catch(noop); },\n notice: (message, payload, labels): void => { g.write(g.entry(gcpMeta(\"NOTICE\", labels), gcpData(message, payload))).catch(noop); },\n warning: (message, payload, labels): void => { g.write(g.entry(gcpMeta(\"WARNING\", labels), gcpData(message, payload))).catch(noop); },\n error: (message, payload, labels): void => { g.write(g.entry(gcpMeta(\"ERROR\", labels), gcpData(message, payload))).catch(noop); },\n critical: (message, payload, labels): void => { g.write(g.entry(gcpMeta(\"CRITICAL\", labels), gcpData(message, payload))).catch(noop); },\n alert: (message, payload, labels): void => { g.write(g.entry(gcpMeta(\"ALERT\", labels), gcpData(message, payload))).catch(noop); },\n emergency: (message, payload, labels): void => { g.write(g.entry(gcpMeta(\"EMERGENCY\", labels), gcpData(message, payload))).catch(noop); },\n });\n }\n\n if (USE_CONSOLE || backends.length === 0) {\n backends.push(CONSOLE_PRETTY\n ? {\n debug: (message, payload): void => { console.log(consoleLine(\"🐞\", message, payload, scope)); },\n info: (message, payload): void => { console.log(consoleLine(\"⚪️\", message, payload, scope)); },\n notice: (message, payload): void => { console.log(consoleLine(\"🔵\", message, payload, scope)); },\n warning: (message, payload): void => { console.log(consoleLine(\"🟡\", message, payload, scope)); },\n error: (message, payload): void => { console.log(consoleLine(\"🔴\", message, payload, scope)); },\n critical: (message, payload): void => { console.log(consoleLine(\"⛔️\", message, payload, scope)); },\n alert: (message, payload): void => { console.log(consoleLine(\"❗️\", message, payload, scope)); },\n emergency: (message, payload): void => { console.log(consoleLine(\"🚨\", message, payload, scope)); },\n }\n : {\n debug: (message, payload): void => { console.log(consolePlain(message, payload, scope)); },\n info: (message, payload): void => { console.log(consolePlain(message, payload, scope)); },\n notice: (message, payload): void => { console.log(consolePlain(message, payload, scope)); },\n warning: (message, payload): void => { console.log(consolePlain(message, payload, scope)); },\n error: (message, payload): void => { console.log(consolePlain(message, payload, scope)); },\n critical: (message, payload): void => { console.log(consolePlain(message, payload, scope)); },\n alert: (message, payload): void => { console.log(consolePlain(message, payload, scope)); },\n emergency: (message, payload): void => { console.log(consolePlain(message, payload, scope)); },\n });\n }\n\n return backends.length === 1\n ? backends[0]\n : {\n debug: (message, payload, labels): void => { backends.forEach(b => b.debug(message, payload, labels)); },\n info: (message, payload, labels): void => { backends.forEach(b => b.info(message, payload, labels)); },\n notice: (message, payload, labels): void => { backends.forEach(b => b.notice(message, payload, labels)); },\n warning: (message, payload, labels): void => { backends.forEach(b => b.warning(message, payload, labels)); },\n error: (message, payload, labels): void => { backends.forEach(b => b.error(message, payload, labels)); },\n critical: (message, payload, labels): void => { backends.forEach(b => b.critical(message, payload, labels)); },\n alert: (message, payload, labels): void => { backends.forEach(b => b.alert(message, payload, labels)); },\n emergency: (message, payload, labels): void => { backends.forEach(b => b.emergency(message, payload, labels)); },\n };\n}\n\nexport default logger;\n"],"mappings":"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","names":[]}
package/dist/index.d.cts CHANGED
@@ -1,14 +1,14 @@
1
+ type LogMethod = (message: string, payload?: Record<string, unknown>, labels?: Record<string, string>) => void;
1
2
  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;
3
+ debug: LogMethod;
4
+ info: LogMethod;
5
+ notice: LogMethod;
6
+ warning: LogMethod;
7
+ error: LogMethod;
8
+ critical: LogMethod;
9
+ alert: LogMethod;
10
+ emergency: LogMethod;
10
11
  }
11
- declare function formatMessage(args: unknown[]): string;
12
- declare const logger: Logger;
12
+ declare function logger(scope?: string): Logger;
13
13
 
14
- export { type Logger, logger as default, formatMessage, logger };
14
+ export { type Logger, logger as default, logger };
package/dist/index.d.ts CHANGED
@@ -1,14 +1,14 @@
1
+ type LogMethod = (message: string, payload?: Record<string, unknown>, labels?: Record<string, string>) => void;
1
2
  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;
3
+ debug: LogMethod;
4
+ info: LogMethod;
5
+ notice: LogMethod;
6
+ warning: LogMethod;
7
+ error: LogMethod;
8
+ critical: LogMethod;
9
+ alert: LogMethod;
10
+ emergency: LogMethod;
10
11
  }
11
- declare function formatMessage(args: unknown[]): string;
12
- declare const logger: Logger;
12
+ declare function logger(scope?: string): Logger;
13
13
 
14
- export { type Logger, logger as default, formatMessage, logger };
14
+ export { type Logger, logger as default, logger };
package/dist/index.js CHANGED
@@ -1,17 +1,5 @@
1
1
  // src/index.ts
2
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
3
  var rawTargets = process.env.LOGGER_TARGET;
16
4
  var targets = rawTargets ? new Set(rawTargets.toLowerCase().split(",").map((s) => s.trim()).filter(Boolean)) : null;
17
5
  var USE_GCP = targets ? targets.has("gcp") : !!process.env.GCP_PROJECT;
@@ -19,151 +7,159 @@ var USE_CONSOLE = targets ? targets.has("console") : !process.env.GCP_PROJECT;
19
7
  var CONSOLE_PRETTY = process.env.LOGGER_CONSOLE_FORMAT?.toLowerCase() === "pretty";
20
8
  var noop = () => {
21
9
  };
22
- var gcpLabels = {};
23
- if (process.env.ENVIRONMENT) gcpLabels.environment = process.env.ENVIRONMENT;
24
- if (process.env.SERVICE_ID) gcpLabels.service_id = process.env.SERVICE_ID;
25
- if (process.env.VERSION) gcpLabels.version = process.env.VERSION;
26
- var GCP_ENV_LABEL = Object.keys(gcpLabels).length ? { labels: gcpLabels } : {};
27
- function consoleLine(emoji, args) {
10
+ var envLabels = {};
11
+ if (process.env.ENVIRONMENT) envLabels.environment = process.env.ENVIRONMENT;
12
+ if (process.env.SERVICE_ID) envLabels.service_id = process.env.SERVICE_ID;
13
+ if (process.env.VERSION) envLabels.version = process.env.VERSION;
14
+ var gcpLog = USE_GCP ? (() => {
15
+ try {
16
+ const logName = process.env.LOGGER_NAME ?? process.env.K_SERVICE ?? "local";
17
+ return new Logging({ projectId: process.env.GCP_PROJECT }).log(logName);
18
+ } catch {
19
+ return null;
20
+ }
21
+ })() : null;
22
+ function consoleLine(emoji, message, payload, scope) {
28
23
  const d = /* @__PURE__ */ new Date();
29
24
  const ts = d.toLocaleString("sv-SE") + "." + String(d.getMilliseconds()).padStart(3, "0");
30
- const last = args[args.length - 1];
31
- const hasPayload = args.length >= 2 && last !== null && typeof last === "object" && !Array.isArray(last) && !(last instanceof Error);
32
- const msg = formatMessage(hasPayload ? args.slice(0, -1) : args);
33
- const suffix = hasPayload ? " " + JSON.stringify(last, null, 2).replace(/\n\s*/g, " ") : "";
34
- return `${emoji} ${ts} ${msg}${suffix}`;
25
+ const scopePart = scope ? `(${scope}) ` : "";
26
+ const suffix = payload ? "\n" + JSON.stringify(payload, null, 2).replace(/^/gm, " ") : "";
27
+ return `${emoji} ${ts} ${scopePart}${message}${suffix}`;
35
28
  }
36
- function consolePlain(args) {
37
- const last = args[args.length - 1];
38
- const hasPayload = args.length >= 2 && last !== null && typeof last === "object" && !Array.isArray(last) && !(last instanceof Error);
39
- const msg = formatMessage(hasPayload ? args.slice(0, -1) : args);
40
- const suffix = hasPayload ? " " + JSON.stringify(last, null, 2).replace(/\n\s*/g, " ") : "";
41
- return `${msg}${suffix}`;
29
+ function consolePlain(message, payload, scope) {
30
+ const scopePart = scope ? `(${scope}) ` : "";
31
+ const suffix = payload ? " " + JSON.stringify(payload, null, 2).replace(/\n\s*/g, " ") : "";
32
+ return `${scopePart}${message}${suffix}`;
42
33
  }
43
- function gcpPayload(args) {
44
- const last = args[args.length - 1];
45
- if (args.length >= 2 && last !== null && typeof last === "object" && !Array.isArray(last) && !(last instanceof Error)) {
46
- return { message: formatMessage(args.slice(0, -1)), ...last };
34
+ function logger(scope) {
35
+ const instanceLabels = {
36
+ ...envLabels,
37
+ ...scope ? { scope } : {}
38
+ };
39
+ function resolveLabels(callLabels) {
40
+ const merged = { ...instanceLabels, ...callLabels };
41
+ return Object.keys(merged).length ? merged : void 0;
47
42
  }
48
- return formatMessage(args);
49
- }
50
- var backends = [];
51
- if (USE_GCP) {
52
- try {
53
- const logName = process.env.LOGGER_NAME ?? process.env.K_SERVICE ?? "local";
54
- const g = new Logging({ projectId: process.env.GCP_PROJECT }).log(logName);
43
+ function gcpMeta(severity, callLabels) {
44
+ const labels = resolveLabels(callLabels);
45
+ return labels ? { severity, labels } : { severity };
46
+ }
47
+ function gcpData(message, payload) {
48
+ return payload ? { message, ...payload } : message;
49
+ }
50
+ const backends = [];
51
+ if (gcpLog) {
52
+ const g = gcpLog;
55
53
  backends.push({
56
- debug: (...args) => {
57
- g.write(g.entry({ severity: "DEBUG", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop);
54
+ debug: (message, payload, labels) => {
55
+ g.write(g.entry(gcpMeta("DEBUG", labels), gcpData(message, payload))).catch(noop);
58
56
  },
59
- info: (...args) => {
60
- g.write(g.entry({ severity: "INFO", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop);
57
+ info: (message, payload, labels) => {
58
+ g.write(g.entry(gcpMeta("INFO", labels), gcpData(message, payload))).catch(noop);
61
59
  },
62
- notice: (...args) => {
63
- g.write(g.entry({ severity: "NOTICE", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop);
60
+ notice: (message, payload, labels) => {
61
+ g.write(g.entry(gcpMeta("NOTICE", labels), gcpData(message, payload))).catch(noop);
64
62
  },
65
- warning: (...args) => {
66
- g.write(g.entry({ severity: "WARNING", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop);
63
+ warning: (message, payload, labels) => {
64
+ g.write(g.entry(gcpMeta("WARNING", labels), gcpData(message, payload))).catch(noop);
67
65
  },
68
- error: (...args) => {
69
- g.write(g.entry({ severity: "ERROR", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop);
66
+ error: (message, payload, labels) => {
67
+ g.write(g.entry(gcpMeta("ERROR", labels), gcpData(message, payload))).catch(noop);
70
68
  },
71
- critical: (...args) => {
72
- g.write(g.entry({ severity: "CRITICAL", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop);
69
+ critical: (message, payload, labels) => {
70
+ g.write(g.entry(gcpMeta("CRITICAL", labels), gcpData(message, payload))).catch(noop);
73
71
  },
74
- alert: (...args) => {
75
- g.write(g.entry({ severity: "ALERT", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop);
72
+ alert: (message, payload, labels) => {
73
+ g.write(g.entry(gcpMeta("ALERT", labels), gcpData(message, payload))).catch(noop);
76
74
  },
77
- emergency: (...args) => {
78
- g.write(g.entry({ severity: "EMERGENCY", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop);
75
+ emergency: (message, payload, labels) => {
76
+ g.write(g.entry(gcpMeta("EMERGENCY", labels), gcpData(message, payload))).catch(noop);
79
77
  }
80
78
  });
81
- } catch {
82
79
  }
83
- }
84
- if (USE_CONSOLE || backends.length === 0) {
85
- backends.push(CONSOLE_PRETTY ? {
86
- debug: (...args) => {
87
- console.log(consoleLine("\u{1F41E}", args));
88
- },
89
- info: (...args) => {
90
- console.log(consoleLine("\u26AA\uFE0F", args));
91
- },
92
- notice: (...args) => {
93
- console.log(consoleLine("\u{1F535}", args));
94
- },
95
- warning: (...args) => {
96
- console.log(consoleLine("\u{1F7E1}", args));
97
- },
98
- error: (...args) => {
99
- console.log(consoleLine("\u{1F534}", args));
100
- },
101
- critical: (...args) => {
102
- console.log(consoleLine("\u26D4\uFE0F", args));
103
- },
104
- alert: (...args) => {
105
- console.log(consoleLine("\u2757\uFE0F", args));
106
- },
107
- emergency: (...args) => {
108
- console.log(consoleLine("\u{1F6A8}", args));
109
- }
110
- } : {
111
- debug: (...args) => {
112
- console.log(consolePlain(args));
80
+ if (USE_CONSOLE || backends.length === 0) {
81
+ backends.push(CONSOLE_PRETTY ? {
82
+ debug: (message, payload) => {
83
+ console.log(consoleLine("\u{1F41E}", message, payload, scope));
84
+ },
85
+ info: (message, payload) => {
86
+ console.log(consoleLine("\u26AA\uFE0F", message, payload, scope));
87
+ },
88
+ notice: (message, payload) => {
89
+ console.log(consoleLine("\u{1F535}", message, payload, scope));
90
+ },
91
+ warning: (message, payload) => {
92
+ console.log(consoleLine("\u{1F7E1}", message, payload, scope));
93
+ },
94
+ error: (message, payload) => {
95
+ console.log(consoleLine("\u{1F534}", message, payload, scope));
96
+ },
97
+ critical: (message, payload) => {
98
+ console.log(consoleLine("\u26D4\uFE0F", message, payload, scope));
99
+ },
100
+ alert: (message, payload) => {
101
+ console.log(consoleLine("\u2757\uFE0F", message, payload, scope));
102
+ },
103
+ emergency: (message, payload) => {
104
+ console.log(consoleLine("\u{1F6A8}", message, payload, scope));
105
+ }
106
+ } : {
107
+ debug: (message, payload) => {
108
+ console.log(consolePlain(message, payload, scope));
109
+ },
110
+ info: (message, payload) => {
111
+ console.log(consolePlain(message, payload, scope));
112
+ },
113
+ notice: (message, payload) => {
114
+ console.log(consolePlain(message, payload, scope));
115
+ },
116
+ warning: (message, payload) => {
117
+ console.log(consolePlain(message, payload, scope));
118
+ },
119
+ error: (message, payload) => {
120
+ console.log(consolePlain(message, payload, scope));
121
+ },
122
+ critical: (message, payload) => {
123
+ console.log(consolePlain(message, payload, scope));
124
+ },
125
+ alert: (message, payload) => {
126
+ console.log(consolePlain(message, payload, scope));
127
+ },
128
+ emergency: (message, payload) => {
129
+ console.log(consolePlain(message, payload, scope));
130
+ }
131
+ });
132
+ }
133
+ return backends.length === 1 ? backends[0] : {
134
+ debug: (message, payload, labels) => {
135
+ backends.forEach((b) => b.debug(message, payload, labels));
113
136
  },
114
- info: (...args) => {
115
- console.log(consolePlain(args));
137
+ info: (message, payload, labels) => {
138
+ backends.forEach((b) => b.info(message, payload, labels));
116
139
  },
117
- notice: (...args) => {
118
- console.log(consolePlain(args));
140
+ notice: (message, payload, labels) => {
141
+ backends.forEach((b) => b.notice(message, payload, labels));
119
142
  },
120
- warning: (...args) => {
121
- console.log(consolePlain(args));
143
+ warning: (message, payload, labels) => {
144
+ backends.forEach((b) => b.warning(message, payload, labels));
122
145
  },
123
- error: (...args) => {
124
- console.log(consolePlain(args));
146
+ error: (message, payload, labels) => {
147
+ backends.forEach((b) => b.error(message, payload, labels));
125
148
  },
126
- critical: (...args) => {
127
- console.log(consolePlain(args));
149
+ critical: (message, payload, labels) => {
150
+ backends.forEach((b) => b.critical(message, payload, labels));
128
151
  },
129
- alert: (...args) => {
130
- console.log(consolePlain(args));
152
+ alert: (message, payload, labels) => {
153
+ backends.forEach((b) => b.alert(message, payload, labels));
131
154
  },
132
- emergency: (...args) => {
133
- console.log(consolePlain(args));
155
+ emergency: (message, payload, labels) => {
156
+ backends.forEach((b) => b.emergency(message, payload, labels));
134
157
  }
135
- });
158
+ };
136
159
  }
137
- var logger = backends.length === 1 ? backends[0] : {
138
- debug: (...args) => {
139
- backends.forEach((b) => b.debug(...args));
140
- },
141
- info: (...args) => {
142
- backends.forEach((b) => b.info(...args));
143
- },
144
- notice: (...args) => {
145
- backends.forEach((b) => b.notice(...args));
146
- },
147
- warning: (...args) => {
148
- backends.forEach((b) => b.warning(...args));
149
- },
150
- error: (...args) => {
151
- backends.forEach((b) => b.error(...args));
152
- },
153
- critical: (...args) => {
154
- backends.forEach((b) => b.critical(...args));
155
- },
156
- alert: (...args) => {
157
- backends.forEach((b) => b.alert(...args));
158
- },
159
- emergency: (...args) => {
160
- backends.forEach((b) => b.emergency(...args));
161
- }
162
- };
163
160
  var index_default = logger;
164
161
  export {
165
162
  index_default as default,
166
- formatMessage,
167
163
  logger
168
164
  };
169
165
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +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.\n// LOGGER_TARGET accepts a comma-separated list of backends: \"gcp\", \"console\", or \"gcp,console\".\nconst rawTargets = process.env.LOGGER_TARGET;\nconst targets = rawTargets\n ? new Set(rawTargets.toLowerCase().split(\",\").map(s => s.trim()).filter(Boolean))\n : null;\n\nconst USE_GCP = targets ? targets.has(\"gcp\") : !!process.env.GCP_PROJECT;\nconst USE_CONSOLE = targets ? targets.has(\"console\") : !process.env.GCP_PROJECT;\nconst CONSOLE_PRETTY = process.env.LOGGER_CONSOLE_FORMAT?.toLowerCase() === \"pretty\";\nconst noop = (): void => {};\nconst gcpLabels: Record<string, string> = {};\nif (process.env.ENVIRONMENT) gcpLabels.environment = process.env.ENVIRONMENT;\nif (process.env.SERVICE_ID) gcpLabels.service_id = process.env.SERVICE_ID;\nif (process.env.VERSION) gcpLabels.version = process.env.VERSION;\nconst GCP_ENV_LABEL = Object.keys(gcpLabels).length ? { labels: gcpLabels } : {};\n\n// Formats a single console log line: \"{emoji} {local timestamp} {message} [{payload}]\"\nfunction consoleLine(emoji: string, args: unknown[]): string {\n const d = new Date();\n const ts = d.toLocaleString(\"sv-SE\") + \".\" + String(d.getMilliseconds()).padStart(3, \"0\");\n const last = args[args.length - 1];\n const hasPayload = args.length >= 2 && last !== null && typeof last === \"object\" && !Array.isArray(last) && !(last instanceof Error);\n const msg = formatMessage(hasPayload ? args.slice(0, -1) : args);\n const suffix = hasPayload ? \" \" + JSON.stringify(last, null, 2).replace(/\\n\\s*/g, \" \") : \"\";\n return `${emoji} ${ts} ${msg}${suffix}`;\n}\n\n// Plain console line: \"message [{payload}]\"\nfunction consolePlain(args: unknown[]): string {\n const last = args[args.length - 1];\n const hasPayload =\n args.length >= 2 &&\n last !== null &&\n typeof last === \"object\" &&\n !Array.isArray(last) &&\n !(last instanceof Error);\n const msg = formatMessage(hasPayload ? args.slice(0, -1) : args);\n const suffix = hasPayload ? \" \" + JSON.stringify(last, null, 2).replace(/\\n\\s*/g, \" \") : \"\";\n return `${msg}${suffix}`;\n}\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\nconst backends: Logger[] = [];\n\nif (USE_GCP) {\n try {\n const logName = process.env.LOGGER_NAME ?? process.env.K_SERVICE ?? \"local\";\n const g = new Logging({ projectId: process.env.GCP_PROJECT }).log(logName);\n backends.push({\n debug: (...args: unknown[]): void => { g.write(g.entry({ severity: \"DEBUG\", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop); },\n info: (...args: unknown[]): void => { g.write(g.entry({ severity: \"INFO\", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop); },\n notice: (...args: unknown[]): void => { g.write(g.entry({ severity: \"NOTICE\", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop); },\n warning: (...args: unknown[]): void => { g.write(g.entry({ severity: \"WARNING\", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop); },\n error: (...args: unknown[]): void => { g.write(g.entry({ severity: \"ERROR\", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop); },\n critical: (...args: unknown[]): void => { g.write(g.entry({ severity: \"CRITICAL\", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop); },\n alert: (...args: unknown[]): void => { g.write(g.entry({ severity: \"ALERT\", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop); },\n emergency: (...args: unknown[]): void => { g.write(g.entry({ severity: \"EMERGENCY\", ...GCP_ENV_LABEL }, gcpPayload(args))).catch(noop); },\n });\n } catch {\n // GCP init failed; will fall back to console\n }\n}\n\nif (USE_CONSOLE || backends.length === 0) {\n backends.push(CONSOLE_PRETTY\n ? {\n debug: (...args: unknown[]): void => { console.log(consoleLine(\"🐞\", args)); },\n info: (...args: unknown[]): void => { console.log(consoleLine(\"⚪️\", args)); },\n notice: (...args: unknown[]): void => { console.log(consoleLine(\"🔵\", args)); },\n warning: (...args: unknown[]): void => { console.log(consoleLine(\"🟡\", args)); },\n error: (...args: unknown[]): void => { console.log(consoleLine(\"🔴\", args)); },\n critical: (...args: unknown[]): void => { console.log(consoleLine(\"⛔️\", args)); },\n alert: (...args: unknown[]): void => { console.log(consoleLine(\"❗️\", args)); },\n emergency: (...args: unknown[]): void => { console.log(consoleLine(\"🚨\", args)); },\n }\n : {\n debug: (...args: unknown[]): void => { console.log(consolePlain(args)); },\n info: (...args: unknown[]): void => { console.log(consolePlain(args)); },\n notice: (...args: unknown[]): void => { console.log(consolePlain(args)); },\n warning: (...args: unknown[]): void => { console.log(consolePlain(args)); },\n error: (...args: unknown[]): void => { console.log(consolePlain(args)); },\n critical: (...args: unknown[]): void => { console.log(consolePlain(args)); },\n alert: (...args: unknown[]): void => { console.log(consolePlain(args)); },\n emergency: (...args: unknown[]): void => { console.log(consolePlain(args)); },\n });\n}\n\nexport const logger: Logger =\n backends.length === 1\n ? backends[0]\n : {\n debug: (...args: unknown[]): void => { backends.forEach(b => b.debug(...args)); },\n info: (...args: unknown[]): void => { backends.forEach(b => b.info(...args)); },\n notice: (...args: unknown[]): void => { backends.forEach(b => b.notice(...args)); },\n warning: (...args: unknown[]): void => { backends.forEach(b => b.warning(...args)); },\n error: (...args: unknown[]): void => { backends.forEach(b => b.error(...args)); },\n critical: (...args: unknown[]): void => { backends.forEach(b => b.critical(...args)); },\n alert: (...args: unknown[]): void => { backends.forEach(b => b.alert(...args)); },\n emergency: (...args: unknown[]): void => { backends.forEach(b => b.emergency(...args)); },\n };\n\nexport default logger;\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { Logging } from \"@google-cloud/logging\";\n\ntype LogMethod = (message: string, payload?: Record<string, unknown>, labels?: Record<string, string>) => void;\n\nexport interface Logger {\n debug: LogMethod;\n info: LogMethod;\n notice: LogMethod;\n warning: LogMethod;\n error: LogMethod;\n critical: LogMethod;\n alert: LogMethod;\n emergency: LogMethod;\n}\n\n// Resolved once at module load — no per-call branching.\n// LOGGER_TARGET accepts a comma-separated list of backends: \"gcp\", \"console\", or \"gcp,console\".\nconst rawTargets = process.env.LOGGER_TARGET;\nconst targets = rawTargets\n ? new Set(rawTargets.toLowerCase().split(\",\").map(s => s.trim()).filter(Boolean))\n : null;\n\nconst USE_GCP = targets ? targets.has(\"gcp\") : !!process.env.GCP_PROJECT;\nconst USE_CONSOLE = targets ? targets.has(\"console\") : !process.env.GCP_PROJECT;\nconst CONSOLE_PRETTY = process.env.LOGGER_CONSOLE_FORMAT?.toLowerCase() === \"pretty\";\nconst noop = (): void => {};\n\nconst envLabels: Record<string, string> = {};\nif (process.env.ENVIRONMENT) envLabels.environment = process.env.ENVIRONMENT;\nif (process.env.SERVICE_ID) envLabels.service_id = process.env.SERVICE_ID;\nif (process.env.VERSION) envLabels.version = process.env.VERSION;\n\n// GCP Log singleton — shared across all logger() calls.\nconst gcpLog = USE_GCP ? (() => {\n try {\n const logName = process.env.LOGGER_NAME ?? process.env.K_SERVICE ?? \"local\";\n return new Logging({ projectId: process.env.GCP_PROJECT }).log(logName);\n } catch {\n return null;\n }\n})() : null;\n\n// Formats a pretty console log line: \"{emoji} {local timestamp} [(scope) ]{message}[\\n {payload}]\"\nfunction consoleLine(emoji: string, message: string, payload?: Record<string, unknown>, scope?: string): string {\n const d = new Date();\n const ts = d.toLocaleString(\"sv-SE\") + \".\" + String(d.getMilliseconds()).padStart(3, \"0\");\n const scopePart = scope ? `(${scope}) ` : \"\";\n const suffix = payload ? \"\\n\" + JSON.stringify(payload, null, 2).replace(/^/gm, \" \") : \"\";\n return `${emoji} ${ts} ${scopePart}${message}${suffix}`;\n}\n\n// Plain console line: \"[(scope) ]{message}[ {payload}]\"\nfunction consolePlain(message: string, payload?: Record<string, unknown>, scope?: string): string {\n const scopePart = scope ? `(${scope}) ` : \"\";\n const suffix = payload ? \" \" + JSON.stringify(payload, null, 2).replace(/\\n\\s*/g, \" \") : \"\";\n return `${scopePart}${message}${suffix}`;\n}\n\nexport function logger(scope?: string): Logger {\n const instanceLabels: Record<string, string> = {\n ...envLabels,\n ...(scope ? { scope } : {}),\n };\n\n function resolveLabels(callLabels?: Record<string, string>): Record<string, string> | undefined {\n const merged = { ...instanceLabels, ...callLabels };\n return Object.keys(merged).length ? merged : undefined;\n }\n\n function gcpMeta(severity: string, callLabels?: Record<string, string>): Record<string, unknown> {\n const labels = resolveLabels(callLabels);\n return labels ? { severity, labels } : { severity };\n }\n\n function gcpData(message: string, payload?: Record<string, unknown>): string | Record<string, unknown> {\n return payload ? { message, ...payload } : message;\n }\n\n const backends: Logger[] = [];\n\n if (gcpLog) {\n const g = gcpLog;\n backends.push({\n debug: (message, payload, labels): void => { g.write(g.entry(gcpMeta(\"DEBUG\", labels), gcpData(message, payload))).catch(noop); },\n info: (message, payload, labels): void => { g.write(g.entry(gcpMeta(\"INFO\", labels), gcpData(message, payload))).catch(noop); },\n notice: (message, payload, labels): void => { g.write(g.entry(gcpMeta(\"NOTICE\", labels), gcpData(message, payload))).catch(noop); },\n warning: (message, payload, labels): void => { g.write(g.entry(gcpMeta(\"WARNING\", labels), gcpData(message, payload))).catch(noop); },\n error: (message, payload, labels): void => { g.write(g.entry(gcpMeta(\"ERROR\", labels), gcpData(message, payload))).catch(noop); },\n critical: (message, payload, labels): void => { g.write(g.entry(gcpMeta(\"CRITICAL\", labels), gcpData(message, payload))).catch(noop); },\n alert: (message, payload, labels): void => { g.write(g.entry(gcpMeta(\"ALERT\", labels), gcpData(message, payload))).catch(noop); },\n emergency: (message, payload, labels): void => { g.write(g.entry(gcpMeta(\"EMERGENCY\", labels), gcpData(message, payload))).catch(noop); },\n });\n }\n\n if (USE_CONSOLE || backends.length === 0) {\n backends.push(CONSOLE_PRETTY\n ? {\n debug: (message, payload): void => { console.log(consoleLine(\"🐞\", message, payload, scope)); },\n info: (message, payload): void => { console.log(consoleLine(\"⚪️\", message, payload, scope)); },\n notice: (message, payload): void => { console.log(consoleLine(\"🔵\", message, payload, scope)); },\n warning: (message, payload): void => { console.log(consoleLine(\"🟡\", message, payload, scope)); },\n error: (message, payload): void => { console.log(consoleLine(\"🔴\", message, payload, scope)); },\n critical: (message, payload): void => { console.log(consoleLine(\"⛔️\", message, payload, scope)); },\n alert: (message, payload): void => { console.log(consoleLine(\"❗️\", message, payload, scope)); },\n emergency: (message, payload): void => { console.log(consoleLine(\"🚨\", message, payload, scope)); },\n }\n : {\n debug: (message, payload): void => { console.log(consolePlain(message, payload, scope)); },\n info: (message, payload): void => { console.log(consolePlain(message, payload, scope)); },\n notice: (message, payload): void => { console.log(consolePlain(message, payload, scope)); },\n warning: (message, payload): void => { console.log(consolePlain(message, payload, scope)); },\n error: (message, payload): void => { console.log(consolePlain(message, payload, scope)); },\n critical: (message, payload): void => { console.log(consolePlain(message, payload, scope)); },\n alert: (message, payload): void => { console.log(consolePlain(message, payload, scope)); },\n emergency: (message, payload): void => { console.log(consolePlain(message, payload, scope)); },\n });\n }\n\n return backends.length === 1\n ? backends[0]\n : {\n debug: (message, payload, labels): void => { backends.forEach(b => b.debug(message, payload, labels)); },\n info: (message, payload, labels): void => { backends.forEach(b => b.info(message, payload, labels)); },\n notice: (message, payload, labels): void => { backends.forEach(b => b.notice(message, payload, labels)); },\n warning: (message, payload, labels): void => { backends.forEach(b => b.warning(message, payload, labels)); },\n error: (message, payload, labels): void => { backends.forEach(b => b.error(message, payload, labels)); },\n critical: (message, payload, labels): void => { backends.forEach(b => b.critical(message, payload, labels)); },\n alert: (message, payload, labels): void => { backends.forEach(b => b.alert(message, payload, labels)); },\n emergency: (message, payload, labels): void => { backends.forEach(b => b.emergency(message, payload, labels)); },\n };\n}\n\nexport default logger;\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@logickernel/logger",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",