Copy link to clipboard
Copied
I have a CF 2018 install (2018.0.13.329786) on Windows Server 2016 Standard and I need to write events to the Windows Event Log. How can I do this?
Hi @CFawesome , I have awesome news. 🙂
The following code is a proof-of-concept. It shows you can infact use ColdFusion to write data to Windows Event Log.
<cfobject type=".NET" name="eventLogClass" class="System.Diagnostics.EventLog">
<!--- Obtain an EventLog instance --->
<cfset eventLog=eventLogClass.init()>
<cfobject type=".NET" name="eventLogEntryType" class="System.Diagnostics.EventLogEntryType">
<!--- EventLogEntryType is a C# enum. "Information" type corresponds to the value 4.--->
<
...
Copy link to clipboard
Copied
First of all, why would ColdFusion want to interact with the Operating System in this way?
Copy link to clipboard
Copied
It is part of a security-related initiative required by my IT department. Can it be done?
Copy link to clipboard
Copied
Can it be done?
By @CFawesome
I'm not sure. But I have an idea that I wish to share with you.
Here's just a sketch, with the hope you will look into it further and fill in the details:
<cfobject type=".NET" name="EventLogObject" class="EventLog" assembly="full_path_to_EventLog_DLL">
<cfset EventLogObject.WriteEntry(source, message, type, eventID, category, rawData)>​
<!--- Argument Types:
source: string,
message: string,
type: System.Diagnostics.EventLogEntryType or enum,
eventID: int,
category: short,
rawData: byte[]
--->
Copy link to clipboard
Copied
Thank you for this suggestion. Please forgive my ignorance of all things .NET, but is that DLL something that should exist on my Windows 2016 standard server or do I need to install some .NET components? I don't see it on the box.
Copy link to clipboard
Copied
As System.Diagnostics.EventLog.dll is a system DLL, I suppose ColdFusion can access the EventLog class directly. If you dump the resulting object, you will see its functions, as well as the signature of each function.
<cfobject type=".NET" name="eventLogClass" class="System.Diagnostics.EventLog">
<cfdump var="#eventLogClass#">
Do a google search of each function and each of the other elements in turn. For example, a search on the web tells you that System.Diagnostics.EventLogEntryType is of type Enum. The value EventLogEntryType.Information is 4. So, to create an EventLog entry of type "Information", I would do something like:
<cfobject type=".NET" name="eventLogEntryType" class="System.Diagnostics.EventLogEntryType">
<cfset eventLogInformationType=eventLogEntryType.Information>
<!--- Alternatively, assuming there will be casting. (Unwise assumption) --->
<!--- <cfset eventLogInformationType=4>--->
I hope I have provided you with enough information for you to start the process of searching, followed by trial and error. That is what I myself have done.
If you got stuck, you might want to consider the following alternative: use Powershell to write to Event Logs.
I copied the following Powershell command from the web, and ran it with ColdFusion's cfexecute. It duly wrote to my Windows 10 Event Logs:
<cfexecute
name="C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe"
arguments=" Write-EventLog -LogName 'Application' -Source 'Application' -EventID 3001 -EntryType Information -Message 'MyApp added a user-requested feature to the display.' -Category 1 -RawData 10,20"
timeout="20">
</cfexecute>
Copy link to clipboard
Copied
Hi @CFawesome , I have awesome news. 🙂
The following code is a proof-of-concept. It shows you can infact use ColdFusion to write data to Windows Event Log.
<cfobject type=".NET" name="eventLogClass" class="System.Diagnostics.EventLog">
<!--- Obtain an EventLog instance --->
<cfset eventLog=eventLogClass.init()>
<cfobject type=".NET" name="eventLogEntryType" class="System.Diagnostics.EventLogEntryType">
<!--- EventLogEntryType is a C# enum. "Information" type corresponds to the value 4.--->
<cfset eventLogInformationType=eventLogEntryType.Information>
<!--- The event source --->
<cfset eventSource="MyTestApplication">
<!--- The event log message, which will be written as 'EventData' --->
<cfset eventMessage="My test event-message is bla-di-bla-di=bla-di-bla">
<!--- Write the message --->
<cfset eventLog.WriteEntry(eventSource, eventMessage, eventLogInformationType)>
Done writing event-data to Windows Event Log.
Run the code, then verify as follows:
Copy link to clipboard
Copied
This works perfectly for what I need. Thank you so much for this information. I really appreciate your time and effort to help me.
Copy link to clipboard
Copied
Nice to hear. I'm glad to have helped.
Copy link to clipboard
Copied
I'll say that I'm not aware of any feature in cf to support it, if that's what you seek specifically. This from both my long experience with it, and from searching for any, as I'm sure you did also.
And as you may have found, others have suggested Java solutions in the past. One seems to be based on log4j1, which is deprecated and may be unsafe to rely on. The other is not, log4jna, available at https://github.com/dblock/log4jna. (It too works with log4j, but it doesn't seem limited to log4j 1, as it seems the other, from what I could find.)
I didn't readily find examples of calling it, but if we could, it is possible to call Java objects from cfml, pretty easily.
But maybe you aren't interested in this line of conjecture, if it isn't built into cf. Let's hear what you think, or what others may add.