UNPKG

@logtail/node

Version:
106 lines 4.37 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Node = void 0; const msgpack_1 = require("@msgpack/msgpack"); const node_http_1 = __importDefault(require("node:http")); const node_https_1 = __importDefault(require("node:https")); const node_zlib_1 = __importDefault(require("node:zlib")); const core_1 = require("@logtail/core"); const context_1 = require("./context"); class Node extends core_1.Base { constructor(sourceToken, options) { options = Object.assign({ timeout: 30000 }, options); super(sourceToken, options); const agent = this.createAgent(); // Sync function const sync = async (logs) => { const nodeOptions = this._options; const request = this.getHttpModule().request(nodeOptions.endpoint, { method: "POST", headers: { "Content-Type": "application/msgpack", "Content-Encoding": "gzip", Authorization: `Bearer ${this._sourceToken}`, "User-Agent": "logtail-js(node)", }, agent, timeout: nodeOptions.timeout > 0 ? nodeOptions.timeout : undefined, }); const response = await new Promise((resolve, reject) => { // Setup timeout handler if timeout is configured if (nodeOptions.timeout > 0) { request.on("timeout", () => { request.destroy(); reject(new Error(`Request timeout after ${nodeOptions.timeout}ms`)); }); } request.on("response", resolve); request.on("error", reject); // Compress the logs using gzip node_zlib_1.default.gzip(this.encodeAsMsgpack(logs), (err, compressedData) => { if (err) { reject(err); return; } request.write(compressedData); request.end(); }); }); if (response.statusCode && response.statusCode >= 200 && response.statusCode < 300) { return logs; } throw new Error(response.statusMessage); }; // Set the throttled sync function this.setSync(sync); } /** * Override `Base` log to enable Node.js streaming * * @param message: string - Log message * @param level (LogLevel) - Level to log at (debug|info|warn|error) * @param context: (Context) - Log context for passing structured data * @param stackContextHint: (StackContextHint|null) - Info about which methods to consider as origin in context.runtime * @returns Promise<ILogtailLog> after syncing */ async log(message, level, context = {}, stackContextHint) { // Process/sync the log, per `Base` logic context = Object.assign(Object.assign({}, (0, context_1.getStackContext)(this, stackContextHint)), context); const processedLog = await super.log(message, level, context); // Push the processed log to the stream, for piping if (this._writeStream) { this._writeStream.write(JSON.stringify(processedLog) + "\n"); } // Return the transformed log return processedLog; } /** * Pipe JSON stringified `ILogtailLog` to a stream after syncing * * @param stream - Writable|Duplex stream */ pipe(stream) { this._writeStream = stream; return stream; } encodeAsMsgpack(logs) { const encoded = (0, msgpack_1.encode)(logs); const buffer = Buffer.from(encoded.buffer, encoded.byteOffset, encoded.byteLength); return buffer; } createAgent() { const nodeOptions = this._options; const family = nodeOptions.useIPv6 ? 6 : 4; return new (this.getHttpModule().Agent)({ family, }); } getHttpModule() { return this._options.endpoint.startsWith("https") ? node_https_1.default : node_http_1.default; } } exports.Node = Node; //# sourceMappingURL=node.js.map