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