strogger
Version:
📊 A modern structured logging library with functional programming, duck-typing, and comprehensive third-party integrations
152 lines • 5.92 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.createSplunkTransport = void 0;
const types_1 = require("../types");
const errors_1 = require("../utils/errors");
const base_transport_1 = require("./base-transport");
const createSplunkTransport = (options = {}) => {
const transportName = "Splunk";
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 hecUrl = options.hecUrl || process.env.SPLUNK_HEC_URL;
const hecToken = options.hecToken || process.env.SPLUNK_HEC_TOKEN;
const source = options.source || "nodejs-logger";
const sourcetype = options.sourcetype || "_json";
const index = options.index || process.env.SPLUNK_INDEX;
const batchSize = options.batchSize || 10;
const flushInterval = options.flushInterval || 5000;
const channel = options.channel || process.env.SPLUNK_CHANNEL;
// Validate required configuration
(0, errors_1.validateEnvironmentVariable)("SPLUNK_HEC_URL", hecUrl, true);
(0, errors_1.validateEnvironmentVariable)("SPLUNK_HEC_TOKEN", hecToken, true);
// Validate transport configuration
(0, errors_1.validateTransportConfig)(transportName, { hecUrl, hecToken }, [
"hecUrl",
"hecToken",
]);
let batch = [];
let flushTimer = null;
const sendToSplunk = async (entries) => {
try {
const payload = entries.map((entry) => ({
event: {
message: entry.message,
level: getSplunkLevel(entry.level),
timestamp: new Date(entry.timestamp).getTime(),
...entry.context,
...(entry.error && {
error_name: entry.error.name,
error_message: entry.error.message,
error_stack: entry.error.stack,
}),
...(entry.metadata && { metadata: entry.metadata }),
},
sourcetype,
source,
...(index && { index }),
...(channel && { channel }),
}));
const response = await fetch(hecUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Splunk ${hecToken}`,
},
body: JSON.stringify(payload),
});
if (!response.ok) {
throw (0, errors_1.createDetailedError)("SPLUNK_API_ERROR", transportName, {
status: response.status,
statusText: response.statusText,
url: hecUrl,
responseBody: await response
.text()
.catch(() => "Unable to read response body"),
});
}
}
catch (error) {
(0, errors_1.handleTransportError)(error, transportName, true);
}
};
const getSplunkLevel = (level) => {
switch (level) {
case types_1.LogLevel.DEBUG:
return "DEBUG";
case types_1.LogLevel.INFO:
return "INFO";
case types_1.LogLevel.WARN:
return "WARN";
case types_1.LogLevel.ERROR:
return "ERROR";
case types_1.LogLevel.FATAL:
return "FATAL";
default:
return "INFO";
}
};
const flush = async () => {
if (batch.length === 0)
return;
const entriesToSend = [...batch];
batch = [];
await sendToSplunk(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,
// Splunk specific methods
flush: async () => {
await flush();
},
close: async () => {
if (flushTimer) {
clearInterval(flushTimer);
flushTimer = null;
}
await flush();
},
// Get current configuration
getConfig: () => ({
hecUrl,
source,
sourcetype,
index,
channel,
batchSize,
flushInterval,
}),
};
}
catch (error) {
(0, errors_1.handleTransportError)(error, transportName, false);
throw error; // Re-throw for proper error handling
}
};
exports.createSplunkTransport = createSplunkTransport;
//# sourceMappingURL=splunk-transport.js.map