tidewave 0.7.0 → 0.8.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.
@@ -1,2 +0,0 @@
1
- export { TidewaveSpanProcessor } from '../logger/tidewave-span-processor';
2
- export { TidewaveLogRecordProcessor } from '../logger/tidewave-log-record-processor';
@@ -1,274 +0,0 @@
1
- import { createRequire } from "node:module";
2
- var __create = Object.create;
3
- var __getProtoOf = Object.getPrototypeOf;
4
- var __defProp = Object.defineProperty;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- function __accessProp(key) {
8
- return this[key];
9
- }
10
- var __toESMCache_node;
11
- var __toESMCache_esm;
12
- var __toESM = (mod, isNodeMode, target) => {
13
- var canCache = mod != null && typeof mod === "object";
14
- if (canCache) {
15
- var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
16
- var cached = cache.get(mod);
17
- if (cached)
18
- return cached;
19
- }
20
- target = mod != null ? __create(__getProtoOf(mod)) : {};
21
- const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
22
- for (let key of __getOwnPropNames(mod))
23
- if (!__hasOwnProp.call(to, key))
24
- __defProp(to, key, {
25
- get: __accessProp.bind(mod, key),
26
- enumerable: true
27
- });
28
- if (canCache)
29
- cache.set(mod, to);
30
- return to;
31
- };
32
- var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
33
- var __returnValue = (v) => v;
34
- function __exportSetter(name, newValue) {
35
- this[name] = __returnValue.bind(null, newValue);
36
- }
37
- var __export = (target, all) => {
38
- for (var name in all)
39
- __defProp(target, name, {
40
- get: all[name],
41
- enumerable: true,
42
- configurable: true,
43
- set: __exportSetter.bind(all, name)
44
- });
45
- };
46
- var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
47
- var __require = /* @__PURE__ */ createRequire(import.meta.url);
48
-
49
- // src/logger/tidewave-logger.ts
50
- import { appendFile, readFile } from "fs/promises";
51
- import * as path from "path";
52
- import * as os from "os";
53
- import * as crypto from "crypto";
54
-
55
- class TidewaveLogger {
56
- logFilePath;
57
- constructor() {
58
- const cwd = process.cwd();
59
- const digest = crypto.createHash("md5").update(cwd).digest("hex").slice(0, 16);
60
- const tempDir = os.tmpdir();
61
- this.logFilePath = path.join(tempDir, `${digest}.tidewave.ndjson`);
62
- }
63
- async addLog(log) {
64
- const line = JSON.stringify(log) + `
65
- `;
66
- try {
67
- await appendFile(this.logFilePath, line, "utf8");
68
- } catch (error) {
69
- console.log("[Tidewave] failed to write to log file, error:", error);
70
- }
71
- }
72
- async getLogs(options) {
73
- let logs = await this.getAllLogs();
74
- if (options?.level) {
75
- const level = options.level.toUpperCase();
76
- logs = logs.filter((log) => log.severityText === level);
77
- }
78
- if (options?.since) {
79
- const sinceDate = new Date(options.since);
80
- logs = logs.filter((log) => new Date(log.timestamp) >= sinceDate);
81
- }
82
- if (options?.grep) {
83
- const regex = new RegExp(options.grep, "i");
84
- logs = logs.filter((log) => regex.test(log.body) || regex.test(JSON.stringify(log.attributes)));
85
- }
86
- if (options?.tail) {
87
- logs = logs.slice(-options.tail);
88
- }
89
- return logs;
90
- }
91
- async getAllLogs() {
92
- try {
93
- const content = await readFile(this.logFilePath, "utf8");
94
- return content.split(`
95
- `).map((line) => {
96
- try {
97
- return JSON.parse(line);
98
- } catch {
99
- return null;
100
- }
101
- }).filter((log) => log !== null);
102
- } catch (error) {
103
- console.log("[Tidewave] failed to read from log file, error:", error);
104
- return [];
105
- }
106
- }
107
- }
108
- var tidewaveLogger;
109
- var init_tidewave_logger = __esm(() => {
110
- tidewaveLogger = new TidewaveLogger;
111
- });
112
-
113
- // src/logger/console-patch.ts
114
- var exports_console_patch = {};
115
- __export(exports_console_patch, {
116
- patchConsole: () => patchConsole
117
- });
118
- function stripAnsiCodes(text) {
119
- return text.replace(ANSI_REGEX, "");
120
- }
121
- function patchConsole() {
122
- const isBrowser = typeof globalThis !== "undefined" && typeof globalThis.window !== "undefined";
123
- if (isBrowser) {
124
- return;
125
- }
126
- if (globalThis.__TIDEWAVE_CONSOLE_PATCHED__) {
127
- return;
128
- }
129
- const severityMap = {
130
- log: "INFO",
131
- info: "INFO",
132
- warn: "WARN",
133
- error: "ERROR",
134
- debug: "DEBUG"
135
- };
136
- Object.entries(severityMap).forEach(([method, severity]) => {
137
- const original = console[method].bind(console);
138
- console[method] = (...args) => {
139
- try {
140
- const body = args.map((arg) => {
141
- if (typeof arg === "string")
142
- return arg;
143
- if (arg instanceof Error) {
144
- return String(arg.stack);
145
- }
146
- if (typeof arg === "object") {
147
- try {
148
- return JSON.stringify(arg);
149
- } catch {
150
- return String(arg);
151
- }
152
- }
153
- return String(arg);
154
- }).map(stripAnsiCodes).join(" ");
155
- const isAllWhitespace = body.match(/^\s+$/);
156
- if (!isAllWhitespace) {
157
- tidewaveLogger.addLog({
158
- timestamp: new Date().toISOString(),
159
- severityText: severity,
160
- body,
161
- attributes: {
162
- "log.origin": "console",
163
- "log.method": method
164
- }
165
- });
166
- }
167
- } catch {}
168
- original(...args);
169
- };
170
- });
171
- globalThis.__TIDEWAVE_CONSOLE_PATCHED__ = true;
172
- }
173
- var ANSI_REGEX;
174
- var init_console_patch = __esm(() => {
175
- init_tidewave_logger();
176
- ANSI_REGEX = /\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g;
177
- });
178
-
179
- // src/next-js/instrumentation.ts
180
- init_console_patch();
181
-
182
- // src/logger/tidewave-span-processor.ts
183
- init_tidewave_logger();
184
-
185
- class TidewaveSpanProcessor {
186
- onStart(_span, _parentContext) {}
187
- onEnd(span) {
188
- try {
189
- const spanType = span.attributes["next.span_type"];
190
- const httpMethod = span.attributes["http.method"];
191
- const relevantSpanTypes = [
192
- "BaseServer.handleRequest",
193
- "AppRender.getBodyResult",
194
- "AppRouteRouteHandlers.runHandler"
195
- ];
196
- if (!spanType || !relevantSpanTypes.includes(spanType)) {
197
- return;
198
- }
199
- const route = span.attributes["next.route"] || span.attributes["http.route"];
200
- const httpUrl = span.attributes["http.url"];
201
- const httpTarget = span.attributes["http.target"];
202
- const httpStatusCode = span.attributes["http.status_code"];
203
- const path2 = route || httpTarget || httpUrl || "unknown";
204
- if (typeof path2 === "string" && path2.startsWith("/tidewave")) {
205
- return;
206
- }
207
- const durationMs = this.calculateDuration(span);
208
- let message = "";
209
- let severity = "INFO";
210
- if (spanType === "BaseServer.handleRequest") {
211
- const method = httpMethod || "UNKNOWN";
212
- const status = httpStatusCode || "unknown";
213
- message = `${method} ${path2} ${status} ${durationMs.toFixed(2)}ms`;
214
- if (typeof httpStatusCode === "number") {
215
- if (httpStatusCode >= 500)
216
- severity = "ERROR";
217
- else if (httpStatusCode >= 400)
218
- severity = "WARN";
219
- }
220
- } else if (spanType === "AppRender.getBodyResult") {
221
- message = `Rendered route: ${route || "unknown"} (${durationMs.toFixed(2)}ms)`;
222
- } else if (spanType === "AppRouteRouteHandlers.runHandler") {
223
- message = `API route: ${route || "unknown"} (${durationMs.toFixed(2)}ms)`;
224
- }
225
- tidewaveLogger.addLog({
226
- timestamp: new Date(span.endTime[0] * 1000 + span.endTime[1] / 1e6).toISOString(),
227
- severityText: severity,
228
- body: message,
229
- attributes: {
230
- "log.origin": "opentelemetry-span",
231
- "span.name": span.name,
232
- "span.kind": span.kind,
233
- "span.type": spanType,
234
- "http.method": httpMethod,
235
- "http.route": route,
236
- "http.status_code": httpStatusCode,
237
- "duration.ms": durationMs
238
- }
239
- });
240
- } catch (_error) {}
241
- }
242
- calculateDuration(span) {
243
- const startTimeMs = span.startTime[0] * 1000 + span.startTime[1] / 1e6;
244
- const endTimeMs = span.endTime[0] * 1000 + span.endTime[1] / 1e6;
245
- return endTimeMs - startTimeMs;
246
- }
247
- async forceFlush() {}
248
- async shutdown() {}
249
- }
250
- // src/logger/tidewave-log-record-processor.ts
251
- init_tidewave_logger();
252
-
253
- class TidewaveLogRecordProcessor {
254
- onEmit(logRecord, _context) {
255
- try {
256
- const body = String(logRecord.body || "");
257
- tidewaveLogger.addLog({
258
- timestamp: new Date(logRecord.hrTime[0] * 1000 + logRecord.hrTime[1] / 1e6).toISOString(),
259
- severityText: logRecord.severityText || "INFO",
260
- body,
261
- attributes: logRecord.attributes
262
- });
263
- } catch (_error) {}
264
- }
265
- async forceFlush() {}
266
- async shutdown() {}
267
- }
268
-
269
- // src/next-js/instrumentation.ts
270
- patchConsole();
271
- export {
272
- TidewaveSpanProcessor,
273
- TidewaveLogRecordProcessor
274
- };