UNPKG

strogger

Version:

📊 A modern structured logging library with functional programming, duck-typing, and comprehensive third-party integrations

131 lines • 5.38 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createNewRelicTransport = void 0; const types_1 = require("../types"); const errors_1 = require("../utils/errors"); const base_transport_1 = require("./base-transport"); const createNewRelicTransport = (options = {}) => { const transportName = "New Relic"; try { let minLevel = options.level ?? types_1.LogLevel.INFO; // Note: formatter is available for custom formatting // const formatter = options.formatter || { // format: (entry: LogEntry) => JSON.stringify(entry), // }; const apiKey = options.apiKey || process.env.NEW_RELIC_LICENSE_KEY; const accountId = options.accountId || process.env.NEW_RELIC_ACCOUNT_ID; const region = options.region || process.env.NEW_RELIC_REGION || "us"; const serviceName = options.serviceName || process.env.NEW_RELIC_SERVICE_NAME; const batchSize = options.batchSize || 10; const flushInterval = options.flushInterval || 5000; // Validate required configuration (0, errors_1.validateEnvironmentVariable)("NEW_RELIC_LICENSE_KEY", apiKey, true); (0, errors_1.validateEnvironmentVariable)("NEW_RELIC_ACCOUNT_ID", accountId, true); // Validate transport configuration (0, errors_1.validateTransportConfig)(transportName, { apiKey, accountId }, [ "apiKey", "accountId", ]); let batch = []; let flushTimer = null; const sendToNewRelic = async (entries) => { try { const url = `https://log-api.${region}.newrelic.com/log/v1`; const payload = { timestamp: Date.now(), service: serviceName, attributes: { // New Relic specific attributes logtype: "application", timestamp: new Date().toISOString(), }, logs: entries.map((entry) => ({ message: entry.message, level: entry.level, timestamp: new Date(entry.timestamp).getTime(), attributes: { ...entry.context, ...(entry.error && { error_name: entry.error.name, error_message: entry.error.message, error_stack: entry.error.stack, }), ...(entry.metadata && { metadata: entry.metadata }), }, })), }; const response = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json", "Api-Key": apiKey, "X-License-Key": apiKey, }, body: JSON.stringify(payload), }); if (!response.ok) { throw (0, errors_1.createDetailedError)("NEW_RELIC_API_ERROR", transportName, { status: response.status, statusText: response.statusText, url, responseBody: await response .text() .catch(() => "Unable to read response body"), }); } } catch (error) { (0, errors_1.handleTransportError)(error, transportName, true); } }; const flush = async () => { if (batch.length === 0) return; const entriesToSend = [...batch]; batch = []; await sendToNewRelic(entriesToSend); }; const startFlushTimer = () => { if (flushTimer) return; flushTimer = setInterval(() => { flush().catch((error) => { (0, errors_1.handleTransportError)(error, transportName, true); }); }, flushInterval); }; // Start the flush timer startFlushTimer(); return { log: async (entry) => { if (!(0, base_transport_1.shouldLog)(entry.level, minLevel)) return; batch.push(entry); if (batch.length >= batchSize) { await flush(); } }, setLevel: (level) => { minLevel = level; }, getLevel: () => minLevel, // New Relic specific methods flush: async () => { await flush(); }, close: async () => { if (flushTimer) { clearInterval(flushTimer); flushTimer = null; } await flush(); }, }; } catch (error) { (0, errors_1.handleTransportError)(error, transportName, false); throw error; // Re-throw for proper error handling } }; exports.createNewRelicTransport = createNewRelicTransport; //# sourceMappingURL=newrelic-transport.js.map