UNPKG

@logtape/windows-eventlog

Version:

Windows Event Log sink for LogTape

115 lines (113 loc) 3.6 kB
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;