@logtape/windows-eventlog
Version:
Windows Event Log sink for LogTape
115 lines (113 loc) • 3.6 kB
JavaScript
const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
const require_types = require('./types.cjs');
const require_platform = require('./platform.cjs');
const require_ffi_deno = require('./ffi.deno.cjs');
const __logtape_logtape = require_rolldown_runtime.__toESM(require("@logtape/logtape"));
//#region sink.deno.ts
/**
* Formats a log record message into a string suitable for Windows Event Log.
* Combines the template and arguments into a readable message.
*/
function formatMessage(record) {
let message = "";
for (let i = 0; i < record.message.length; i++) if (i % 2 === 0) message += record.message[i];
else {
const arg = record.message[i];
if (typeof arg === "string") message += arg;
else message += JSON.stringify(arg);
}
return message;
}
/**
* Formats additional context information for the log entry.
* Includes category, properties, and other metadata.
*/
function formatContext(record) {
const context = [];
if (record.category && record.category.length > 0) context.push(`Category: ${record.category.join(".")}`);
if (record.properties && Object.keys(record.properties).length > 0) context.push(`Properties: ${JSON.stringify(record.properties)}`);
context.push(`Timestamp: ${new Date(record.timestamp).toISOString()}`);
return context.length > 0 ? `\n\n${context.join("\n")}` : "";
}
/**
* Maps LogTape log levels to Windows Event Log types.
*/
function getEventType(level) {
switch (level) {
case "fatal":
case "error": return require_ffi_deno.EVENTLOG_ERROR_TYPE;
case "warning": return require_ffi_deno.EVENTLOG_WARNING_TYPE;
case "info":
case "debug":
case "trace":
default: return require_ffi_deno.EVENTLOG_INFORMATION_TYPE;
}
}
/**
* Creates a Windows Event Log sink for Deno environments using FFI.
*
* This implementation uses Deno's Foreign Function Interface to directly
* call Windows Event Log APIs, providing reliable Event Log integration
* without depending on external packages.
*
* @param options Configuration options for the sink
* @returns A LogTape sink that writes to Windows Event Log
* @throws {WindowsPlatformError} If not running on Windows
* @throws {WindowsEventLogError} If Event Log operations fail
*
* @example
* ```typescript
* import { getWindowsEventLogSink } from "@logtape/windows-eventlog";
*
* const sink = getWindowsEventLogSink({
* sourceName: "MyApp"
* });
* ```
*
* @since 1.0.0
*/
function getWindowsEventLogSink(options) {
require_platform.validateWindowsPlatform();
const { sourceName, eventIdMapping = {} } = options;
const eventIds = {
...require_types.DEFAULT_EVENT_ID_MAPPING,
...eventIdMapping
};
let ffi = null;
const metaLogger = (0, __logtape_logtape.getLogger)([
"logtape",
"meta",
"windows-eventlog"
]);
const sink = (record) => {
if (!ffi) try {
ffi = new require_ffi_deno.WindowsEventLogFFI(sourceName);
ffi.initialize();
} catch (error) {
metaLogger.error("Failed to initialize Windows Event Log FFI: {error}", { error });
return;
}
const message = formatMessage(record);
const context = formatContext(record);
const fullMessage = message + context;
const eventType = getEventType(record.level);
const eventId = eventIds[record.level];
try {
ffi.writeEvent(eventType, eventId, fullMessage);
} catch (error) {
metaLogger.error("Failed to write {level} message to Windows Event Log: {error}", {
level: record.level,
error
});
}
};
sink[Symbol.dispose] = () => {
if (ffi) {
ffi.dispose();
ffi = null;
}
};
return sink;
}
//#endregion
exports.getWindowsEventLogSink = getWindowsEventLogSink;