Event Log(Event log created event) - c#

I would like to know if how can we catch the event in C# when a system event log is created. Also I would like to know if how can I get only ERROR LOGS from Windows event logs using C#.
I have the following code but it just returns me all logs. I just need ERROR logs:
System.Diagnostics.EventLog eventLog1 = new System.Diagnostics.EventLog("Application", Environment.MachineName);
int i = 0;
foreach (System.Diagnostics.EventLogEntry entry in eventLog1.Entries)
{
Label1.Text += "Log is : " + entry.Message + Environment.NewLine;
}

You can use CreateEventSource static method of EventLog class to create event log like
EventLog.CreateEventSource("MyApp","Application");
EventLog class present in System.Diagnostics namespace.
You can use WriteEntry() method to write to the event log. EventLogEntryType enum can be used to specify the type of event you want to log. An example below
EventLog.WriteEntry(sSource, sEvent, EventLogEntryType.Warning, 234);
See How to write to an event log by using Visual C#
if you are looking for reading only ERROR level log then you can use the below code block. You just need to check EntryType of the eventlog entry and then print/display accordingly.
static void Main(string[] args)
{
EventLog el = new EventLog("Application", "MY-PC");
foreach (EventLogEntry entry in el.Entries)
{
if (entry.EntryType == EventLogEntryType.Error)
{
Console.WriteLine(entry.Message);
}
}
}

Related

EventLog selecting source that has not been previously created

I've been using the following basic code which I took from a website to write messages to the Windows Event Log using the EventLog class from System.Diagnostics
class Program
{
static void Main(string[] args)
{
WriteEventLogEntry("This is an entry in the event log");
}
private static void WriteEventLogEntry(string message)
{
// Create an instance of EventLog
System.Diagnostics.EventLog eventLog = new System.Diagnostics.EventLog();
// Check if the event source exists. If not create it.
if (!System.Diagnostics.EventLog.SourceExists("TestApplication"))
{
System.Diagnostics.EventLog.CreateEventSource("TestApplication", "Application");
}
// Set the source name for writing log entries.
eventLog.Source = "TestApplicationNotExisting";
// Create an event ID to add to the event log
int eventID = 8;
// Write an entry to the event log.
eventLog.WriteEntry(message,
System.Diagnostics.EventLogEntryType.Error,
eventID);
// Close the Event Log
eventLog.Close();
}
}
I've tweaked the code above so that the Source that is being selected is one that I have not previously created using the CreateEventSource method. I expected this to throw an exception but instead it works perfectly well and I have a message in the Event Log from source "TestApplicationNotExisting".
Why is this not throwing an exception? if I can select sources on the fly then what's the point of the CreateEventSource method?

How can I log LoggingChannel LogMessages to the StorageFile?

I want to add logging of exceptions to my Windows Store App. Based on an idea from here, I've started off with this code in App.xaml.cs:
sealed partial class App : Application
{
private LoggingChannel channel;
private LoggingSession session;
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public App()
{
this.InitializeComponent();
this.Suspending += OnSuspending;
channel = new LoggingChannel("PlatypiChannel");
session = new LoggingSession("PlatypiSession");
session.AddLoggingChannel(channel, LoggingLevel.Error);
UnhandledException += Application_UnhandledException;
}
async private void Application_UnhandledException(object sender, UnhandledExceptionEventArgs ex)
{
ex.Handled = true;
String exceptionCornucopia = String.Format("Message0 == {0}; Message1 == {1}; HResult == {2}; Inner Ex == {3}; StackTrace == {4}", ex.Message, ex.Exception.Message, ex.Exception.HResult, ex.Exception.InnerException, ex.Exception.StackTrace);
channel.LogMessage(exceptionCornucopia, LoggingLevel.Error);
// not seeing how this saves the channel's logged messages...???
StorageFile logFile = await session.SaveToFileAsync(ApplicationData.Current.LocalFolder, "CrashLog");
}
As the comment indicates, it seems to me the last line simply saves a file named "CrashLog" to the LocalFolder. But how do the LogMessages get into that file? There is obviously a key piece missing here.
I know that this question has been open for a long time, but I just want to provide an answer for anyone else finding this.
The secret here is that the LogMessages are all written into the LoggingChannel, which itself has previously been registered with the LoggingSession:
session.AddLoggingChannel(channel, LoggingLevel.Error);
When the session is then saved to a file, it obviously knows about the associated channels and where to search for pending log messages.

Handling AppDomain.CurrentDomain.UnhandledException in windows service

I have window service which acts as a sync software. I want to add unhanded exception logging on my service, so I modified my program.cs like this:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]
static void Main()
{
// Register Unhandled Exception Handler
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(UnhandledExceptionHandler);
// Run Service
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service()
};
ServiceBase.Run(ServicesToRun);
}
static void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs args)
{
// Get Exception
Exception ex = (Exception)args.ExceptionObject;
// Generate Error
string ErrorMessage = String.Format(
"Error: {0}\r\n" +
"Runtime Terminating: {1}\r\n----- ----- ----- ----- ----- -----\r\n\r\n" +
"{2}\r\n\r\n####################################\r\n",
ex.Message,
args.IsTerminating,
ex.StackTrace.Trim());
// Write Error To File
try
{
using (StreamWriter sw = File.AppendText("UnhandledExceptions.log"))
sw.WriteLine(errorMessage);
}
catch { }
}
}
Then on my Service.cs file, in the OnStart method, I added a throw new Exception("test"); to see if unhanded exceptions are being logged to file as expected.
When I start my service, it stops immediately as expected; however it doesn't seem to be logging the exception to the specified file.
Any idea what I am doing wrong here? Thanks in advance for any help.
Before you ask, my service runs as Local Service and the directory where my service .exe runs from (c:\mysync) already has Local Service added in the security tab with full read/write access.
OnStart is called in Service base class inside try-catch block. If an exception happens on this stage it catches it and just set a status 1 as a result and do not throw it further:
string[] args = (string[]) state;
try
{
this.OnStart(args);
.....
}
catch (Exception ex)
{
this.WriteEventLogEntry(Res.GetString("StartFailed", new object[1]
{
(object) ((object) ex).ToString()
}), EventLogEntryType.Error);
this.status.currentState = 1;
}
As a result you can find a record in EventLogs, but you can't catch it as an unhanded domain exception, as there is no such exception.
using (StreamWriter sw = File.AppendText("UnhandledExceptions.log"))
It is forever a really bad idea to not use full path names for files (like c:\foo\bar.log). Especially in a service, you have very little control over the default directory for your service. Because it is started by the service control manager, not by the user from the command prompt or a desktop shortcut.
So high odds that you are just looking at the wrong file. The real one probably ended up being written to c:\windows\system32 (or syswow64). The operating system directories are normally write protected but that doesn't work for a service, they run with a highly privileged account so can litter the hard drive anywhere.
Always use full path names. Using the EventLog instead is highly recommended.

Event log write error

It is simple, I want to write something to event log.
protected override void OnStop()
{
// TODO: Add code here to perform any tear-down necessary to stop your service.
if (!System.Diagnostics.EventLog.SourceExists("IvrService"))
{
System.Diagnostics.EventLog.CreateEventSource(
"IvrService", "IvrServiceLog");
}
EventLog eventLog1 = new System.Diagnostics.EventLog();
eventLog1.Source = "IvrService";
eventLog1.Log = "IvrServiceLog";
try
{
eventLog1.WriteEntry("Successfully "+State.Stopped.ToString());
IvrApplication.StopImmediate();
}
catch (Exception ex)
{
// eventLog1.WriteEntry(ex.Message);
}
}
The exception is:
Failed to stop service. System.ArgumentException: The source 'IvrService' is not registered in log 'IvrServiceLog'. (It is registered in log 'Application'.) " The Source and Log properties must be matched, or you may set Log to the empty string, and it will automatically be matched to the Source property.
at System.Diagnostics.EventLogInternal.VerifyAndCreateSource(String sourceName, String currentMachineName)
at System.Diagnostics.EventLogInternal.WriteEntry(String message, EventLogEntryType type, Int32 eventID, Int16 category, Byte[] rawData)
at System.Diagnostics.EventLog.WriteEntry(String message)
The error message is telling you exactly what is wrong. You have the Event Source IvrService registered with the Application Log, not the IvrServiceLog. The System.Diagnostics.EventLog.SourceExists verifies that the source exists, but not for a particular log.
My guess is that you originally registered this with the Application log and then later changed it to write to the IvrServiceLog.
To clean up your development machine, you could simply run the following and then you code should work going forward.
System.Diagnostics.EventLog.DeleteEventSource("IvrService");

Windows Event Log

I am developing an app to capture event logs (security) from multiple Windows systems. I have a handler to EntryWritten. I am able to map most fields from the Event Viewer to the EntryWrittenEventArgs entry in .net. However, I cannot seem to find the mappings for the Level, OpCode and Task Category fields which show up in Event Viewer. Any ideas on how I get this in vb.net or c#? Thanks
The EventLog class in the System.Diagnostics namespace does not contain fields for Level, OpCode or Task. There is, however, the EventRecord class in the System.Diagnostics.Eventing.Reader namespace which is capable of returning those fields. Note that this namespace is mainly used for retrieving event logs from a remote machine. Even though you could use it to get logs on the local machine as well, it opens a local pipe to the system, which makes it slower than the EventLog class. If you really need to access those fields though, this is how this class is generally used:
private void LoadEventLogs()
{
List<EventRecord> eventLogs = new List<EventRecord>();
EventLogSession session = new EventLogSession();
foreach (string logName in session.GetLogNames())
{
EventLogQuery query = new EventLogQuery(logName, PathType.LogName);
query.TolerateQueryErrors = true;
query.Session = session;
EventLogWatcher logWatcher = new EventLogWatcher(query);
logWatcher.EventRecordWritten +=
new EventHandler<EventRecordWrittenEventArgs>(LogWatcher_EventRecordWritten);
try
{
logWatcher.Enabled = true;
}
catch (EventLogException) { }
// This is how you'd read the logs
//using (EventLogReader reader = new EventLogReader(query))
//{
// for (EventRecord eventInstance = reader.ReadEvent(); eventInstance != null; eventInstance = reader.ReadEvent())
// {
// eventLogs.Add(eventInstance);
// }
//}
}
}
And the LogWatcher_EventRecordWritten event handler:
private void LogWatcher_EventRecordWritten(object sender, EventRecordWrittenEventArgs e)
{
var level = e.EventRecord.Level;
var task = e.EventRecord.TaskDisplayName;
var opCode = e.EventRecord.OpcodeDisplayName;
// Other properties
}
Note that I wrapped the logWatcher.Enabled = true; statement in a try-catch block, because not all sources allow entry-written listeners (security should work fine). The commented-out section shows you an example of reading all the logs, if you need it.

Categories