@logtape/windows-eventlog
Version:
Windows Event Log sink for LogTape
116 lines (114 loc) • 3.93 kB
JavaScript
const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
const require_types = require('./types.cjs');
const __logtape_logtape = require_rolldown_runtime.__toESM(require("@logtape/logtape"));
//#region ffi.deno.ts
const EVENTLOG_ERROR_TYPE = 1;
const EVENTLOG_WARNING_TYPE = 2;
const EVENTLOG_INFORMATION_TYPE = 4;
const FFI_SYMBOLS = {
RegisterEventSourceA: {
parameters: ["pointer", "pointer"],
result: "pointer"
},
DeregisterEventSource: {
parameters: ["pointer"],
result: "u32"
},
ReportEventA: {
parameters: [
"pointer",
"u16",
"u16",
"u32",
"pointer",
"u16",
"u32",
"pointer",
"pointer"
],
result: "u32"
}
};
/**
* Windows Event Log FFI wrapper class for Deno.
* Provides direct access to Windows Event Log APIs through Deno's FFI.
*
* @since 1.0.0
*/
var WindowsEventLogFFI = class {
lib = null;
eventSource = null;
encoder = new TextEncoder();
metaLogger = (0, __logtape_logtape.getLogger)([
"logtape",
"meta",
"windows-eventlog"
]);
constructor(sourceName) {
this.sourceName = sourceName;
}
/**
* Initializes the FFI library and registers the event source.
* @throws {WindowsEventLogError} If initialization fails
*/
initialize() {
try {
this.lib = Deno.dlopen("advapi32.dll", FFI_SYMBOLS);
const sourceNamePtr = Deno.UnsafePointer.of(this.encoder.encode(this.sourceName + "\0"));
this.eventSource = this.lib.symbols.RegisterEventSourceA(null, sourceNamePtr);
if (!this.eventSource) throw new require_types.WindowsEventLogError(`Failed to register event source '${this.sourceName}'.`);
} catch (error) {
if (error instanceof require_types.WindowsEventLogError) throw error;
throw new require_types.WindowsEventLogError(`Failed to initialize Windows Event Log FFI: ${error instanceof Error ? error.message : String(error)}`, error instanceof Error ? error : void 0);
}
}
/**
* Writes a message to the Windows Event Log.
*
* @param eventType Event type (error, warning, info)
* @param eventId Event ID number
* @param message Message string to log
* @throws {WindowsEventLogError} If the write operation fails
*/
writeEvent(eventType, eventId, message) {
if (!this.lib || !this.eventSource) throw new require_types.WindowsEventLogError("FFI not initialized. Call initialize() first.");
try {
const messageBuffer = this.encoder.encode(message + "\0");
const messagePtr = Deno.UnsafePointer.of(messageBuffer);
const messagePtrValue = messagePtr ? Deno.UnsafePointer.value(messagePtr) : 0n;
const stringsArray = new BigUint64Array([messagePtrValue]);
const stringsPtr = Deno.UnsafePointer.of(stringsArray);
const result = this.lib.symbols.ReportEventA(this.eventSource, eventType, 0, eventId, null, 1, 0, stringsPtr, null);
if (result === 0) throw new require_types.WindowsEventLogError(`Failed to write event to Event Log.`);
} catch (error) {
if (error instanceof require_types.WindowsEventLogError) throw error;
throw new require_types.WindowsEventLogError(`Error writing to Event Log: ${error instanceof Error ? error.message : String(error)}`, error instanceof Error ? error : void 0);
}
}
/**
* Cleans up resources and deregisters the event source.
*/
dispose() {
if (this.lib && this.eventSource) {
try {
this.lib.symbols.DeregisterEventSource(this.eventSource);
} catch (error) {
this.metaLogger.error("Failed to deregister event source during cleanup: {error}", { error });
}
this.eventSource = null;
}
if (this.lib) {
try {
this.lib.close();
} catch (error) {
this.metaLogger.error("Failed to close FFI library during cleanup: {error}", { error });
}
this.lib = null;
}
}
};
//#endregion
exports.EVENTLOG_ERROR_TYPE = EVENTLOG_ERROR_TYPE;
exports.EVENTLOG_INFORMATION_TYPE = EVENTLOG_INFORMATION_TYPE;
exports.EVENTLOG_WARNING_TYPE = EVENTLOG_WARNING_TYPE;
exports.WindowsEventLogFFI = WindowsEventLogFFI;