@logtape/windows-eventlog
Version:
Windows Event Log sink for LogTape
117 lines (115 loc) • 3.98 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 src/ffi.deno.ts
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 WindowsEventLogDenoFFI = class {
lib = null;
eventSource = null;
sourceName = "";
initialized = false;
encoder = new TextEncoder();
metaLogger = (0, __logtape_logtape.getLogger)([
"logtape",
"meta",
"windows-eventlog"
]);
/**
* Initializes the FFI library and registers the event source.
* @throws {WindowsEventLogError} If initialization fails
*/
initialize(sourceName) {
this.sourceName = sourceName;
if (this.initialized) return;
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}'.`);
this.initialized = true;
} 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 that gives us formatting string
* @param params Message parameter strings to log
* @throws {WindowsEventLogError} If the write operation fails
*/
writeEvent(eventType, eventId, params) {
if (!this.lib || !this.eventSource) throw new require_types.WindowsEventLogError("FFI not initialized. Call initialize() first.");
try {
const unsafePointersToStrings = [];
for (let i = 0; i < params.length; i++) {
const paramBuffer = this.encoder.encode(params[i] + "\0");
const paramPtr = Deno.UnsafePointer.of(paramBuffer);
const paramPtrValue = paramPtr ? Deno.UnsafePointer.value(paramPtr) : 0n;
unsafePointersToStrings.push(paramPtrValue);
}
const stringsArray = new BigUint64Array(unsafePointersToStrings);
const stringsPtr = Deno.UnsafePointer.of(stringsArray);
const result = this.lib.symbols.ReportEventA(this.eventSource, eventType, 0, eventId, null, stringsArray.length, 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;
}
this.initialized = false;
}
};
//#endregion
exports.WindowsEventLogDenoFFI = WindowsEventLogDenoFFI;