UNPKG

@logtape/windows-eventlog

Version:

Windows Event Log sink for LogTape

101 lines (99 loc) 3.09 kB
import { DEFAULT_EVENT_ID_MAPPING, mapLogLevelToEventType } from "./types.js"; import { validateWindowsPlatform } from "./platform.js"; import { WindowsEventLogFFI } from "./ffi.bun.js"; import { getLogger } from "@logtape/logtape"; //#region sink.bun.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")}` : ""; } /** * Creates a Windows Event Log sink for Bun environments using FFI. * * This implementation uses Bun's native Foreign Function Interface to directly * call Windows Event Log APIs, providing high performance logging optimized * for the Bun runtime. * * @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) { validateWindowsPlatform(); const { sourceName, eventIdMapping = {} } = options; const eventIds = { ...DEFAULT_EVENT_ID_MAPPING, ...eventIdMapping }; let ffi = null; const metaLogger = getLogger([ "logtape", "meta", "windows-eventlog" ]); const sink = (record) => { if (!ffi) { ffi = new WindowsEventLogFFI(sourceName); try { ffi.initialize(); } catch (error) { metaLogger.error("Failed to initialize Windows Event Log FFI: {error}", { error }); ffi = null; return; } } const message = formatMessage(record); const context = formatContext(record); const fullMessage = message + context; const eventType = mapLogLevelToEventType(record.level); const eventId = eventIds[record.level]; if (ffi) try { ffi.writeEvent(eventType, eventId, fullMessage); } catch (error) { metaLogger.error("Failed to write to Windows Event Log: {error}", { error }); } }; sink[Symbol.dispose] = () => { if (ffi) { ffi.dispose(); ffi = null; } }; return sink; } //#endregion export { getWindowsEventLogSink }; //# sourceMappingURL=sink.bun.js.map