读取Windows EventLog
读取Windows EventLog
我在尝试读取用户VDI连接数据,以便统计用户的访问时长的过程中,首先发现 .evtx文件只能用Windows事件查看器不会乱码,其次发现通过System.Diagnostics.EventLog找不到VDI的log,也就没办法自动获取VDI数据,不得已:把VDI evtx文件复制到指定文件夹,程序到指定文件夹读取,此时需要用System.Diagnostics.Eventing.Reader然后压缩备份到另一个文件夹(不同的事件ID有不同的属性内容,详细的属性内容可以参考Windows事件查看器的某条Log的详细信息,如此就知道哪个属性Value是我们想要的了.
这里是:建议用Eventing.Reader读取Windows相关EventLog
通过EventLog获取日志
通过EventLog获取日志,Sample1
先展示下面的 代码片
.
// 如果已经引用using System.Diagnostics,则可以直接写:EventLog[]
System.Diagnostics.EventLog[] EventLogList;
//指定電腦上的所有事件記錄檔,並建立含有清單的 EventLog 物件陣列
EventLogList= System.Diagnostics.EventLog.GetEventLogs(".");
//不管是在我个人电脑还是在VDI服务器上:EventLogList.Length都是9
Console.WriteLine("Number of logs on computer: " + EventLogList.Length);
//显示Log名称和每个Log的事件个数(Security需要管理员权限)
foreach (System.Diagnostics.EventLog log in EventLogList)
{
Console.WriteLine();
Console.WriteLine(" Log name = \t {0}", log.Log);
Console.WriteLine(" Number of event log entries = {0}", log.Entries.Count.ToString());
// "Application"应用程序, "Security"安全, "System"系统
//以Application为例,大同小异
if (log.Log=="Application")
{
DateTime EventCreateTime;
string EventID, EventMessage, Param1, Param2, Param3;
foreach (EventLogEntry eventLog in log.Entries)
{
EventID = eventLog.InstanceId.ToString();
if (EventID == "4625")
{
EventMessage = eventLog.Message;
EventCreateTime = eventLog.TimeGenerated;
Param1 = eventLog.ReplacementStrings[0].ToString();
Param2 = eventLog.ReplacementStrings[1].ToString();
Param3 = eventLog.ReplacementStrings[2].ToString();
}
}
}
}
通过EventLog获取日志,Sample2
先展示下面的 代码片
.
//"Application"应用程序, "Security"安全, "System"系统
EventLog myEventLog = new EventLog("Application");
Console.WriteLine(" Number of Eventlog = {0}", myEventLog.Entries.Count.ToString());
//
DateTime EventCreateTime;
string EventID, EventMessage, Param1, Param2, Param3;
foreach (EventLogEntry eventLog in myEventLog.Entries)
{
EventID = eventLog.InstanceId.ToString();
if (EventID == "4625")
{
EventMessage = eventLog.Message;
EventCreateTime = eventLog.TimeGenerated;
Param1 = eventLog.ReplacementStrings[0].ToString();
Param2 = eventLog.ReplacementStrings[1].ToString();
Param3 = eventLog.ReplacementStrings[2].ToString();
}
}
Eventing.Reader读取特定路径或Log名称的完整示例
在App.config中设定参数
注意 appSettings
中的内容.
<appSettings>
<!--VDI日志目录路径-->
<add key="VDILogPath" value="C:\EventLog\VDI"/>
<!--VDI日志名称-->
<add key="VDILogName" value="VDILog.evtx"/>
<!--VDI日志备份目录路径-->
<add key="LogBackupPath" value="C:\EventLog\Backup"/>
</appSettings>
读取App.config中设定的参数
string VDILogPath = ConfigurationManager.AppSettings["VDILogPath"].ToString();
string VDILogName = ConfigurationManager.AppSettings["VDILogName"].ToString();
string LogBackupPath = ConfigurationManager.AppSettings["LogBackupPath"].ToString();
**注意要引用:System.Configuration.dll;**否则ConfigurationManager无效
基本代码(读取、分析、备份)
注意要引用using System.Diagnostics.Eventing.Reader
static void Main(string[] args)
{
//读参数中的VDILog所在文件夹
string VDILogPath = ConfigurationManager.AppSettings["VDILogPath"].ToString();
//读VDILog的名称
string VDILogName = ConfigurationManager.AppSettings["VDILogName"].ToString();
//拼接在一起
string eventLogLocation = VDILogPath + "\\" + VDILogName;
Console.WriteLine("VDI Log Path: "+ eventLogLocation );
//C:\EventLog\VDI\VDILog.evtx
//EventLogQuery后面的参数示例,一个是通过指定文件夹 一个是通过指定Log名称
EventLogQuery eventLogQuery = new EventLogQuery(eventLogLocation, PathType.FilePath);
//EventLogQuery eventLogQuery = new EventLogQuery("Application", PathType.LogName);
try
{
//LogName=eventLogLocation
EventLogReader eventlogReader = new EventLogReader(eventLogQuery);
// Display event info
DisplayEventAndLogInformationForVDI(eventlogReader, eventLogLocation);
}
catch (EventLogNotFoundException e)
{
Console.WriteLine("Could not Find the VDI Log to Query! " + e.Message);
return;
}
}
private static void DisplayEventAndLogInformationForVDI(EventLogReader logReader, string SourceLocation)
{
//VDI 303事件所需要的变量
string LoginDateTime = "";
Int32 ConnectedSecond = 0;
string LoginDate = "";
string LoginTime = "";
string UserID = "";
int Count303Type = 0;//303事件数量
int InsertCount = 0;//成功插入DB的数量
int TotalCount = 0;//EventLog中的事件数量
string DBResult = "Ok";// InitDBInfo();初始化数据库省略
if (DBResult != "Ok")
{
Console.WriteLine("DB Connect Fail: {0}", DBResult);
}
else
{
for (EventRecord eventInstance = logReader.ReadEvent();
null != eventInstance; eventInstance = logReader.ReadEvent())
{
TotalCount++;
Console.WriteLine("-----------------------------------------------------");
Console.WriteLine("Event ID: {0}", eventInstance.Id);
//Link DB For Query or Insert
if (eventInstance.Id.ToString() == "303")
{
Count303Type++;
LoginDateTime = eventInstance.TimeCreated.ToString();//2022/4/30 13:34:39
LoginDate = Convert.ToDateTime(LoginDateTime).ToString("yyyy-MM-dd");//2022-04-30
LoginTime = Convert.ToDateTime(LoginDateTime).ToString("HH:mm:ss");//13:32:13
//从属性中读数据
UserID = eventInstance.Properties[0].Value.ToString().Substring(3).ToUpper();//A0236602
ConnectedSecond = Convert.ToInt32(eventInstance.Properties[6].Value);
//显示在程序界面的内容
Console.WriteLine("UserID: {0}", UserID);
Console.WriteLine("ConnectSeconds: {0}", ConnectedSecond);
Console.WriteLine("LoginTimeFull: {0}", LoginDateTime);
Console.WriteLine("LoginDate: {0}", LoginDate);
Console.WriteLine("LoginTime: {0}", LoginTime);
//插入DB的部分...
}
}
}
Console.WriteLine("-----------------------------------------------------");
Console.WriteLine("TotalRecord: {0}, 303Type Record:{1}, Insert OK Record:{2}", TotalCount, Count303Type, InsertCount);
Console.WriteLine("-----------------------------------------------------");
//参数文件中读取备份路径
string LogFileBackupPath = ConfigurationManager.AppSettings["LogBackupPath"].ToString();
//如果不存在就创建file文件夹
if (Directory.Exists(LogFileBackupPath) == false)
{
Directory.CreateDirectory(LogFileBackupPath);
}
//产生一个随机数
Random random = new Random(System.Environment.TickCount);
int randomNumber = random.Next(1001, 9999);
//备份文件路径和名称
string LogFileBackupFile = LogFileBackupPath + "\\" + DateTime.Now.ToString("yyyyMMddHHmmss")+ randomNumber + ".evtx";
//源文件路径和名称
string LogSourceLocation = SourceLocation;
//移动到备份路径,不能用Move,因为文件在使用中
File.Copy(LogSourceLocation, LogFileBackupFile);
//如果要压缩则可以用下面的方法
LogFileBackupFile = LogFileBackupPath + "\\" + DateTime.Now.ToString("yyyyMMddHHmmss")+ randomNumber + ".zip";
ZipHelper.CreateZip(LogSourceLocation, LogFileBackupFile);
//处理完毕后,窗口自动关闭
//如果不想自动关闭,可以增加下面的两行代码
Console.WriteLine("Press [Enter] To Exist");
Console.ReadLine();
}
压缩Helper
也很简单,把这个加入项目即可,但需要:ICSharpCode.SharpZipLib.dll
public class ZipHelper
{
/// <summary>
/// 压缩文件
/// </summary>
/// <param name="sourceFilePath"></param>
/// <param name="destinationZipFilePath"></param>
public static void CreateZip(string sourceFilePath, string destinationZipFilePath)
{
ZipOutputStream zipStream = new ZipOutputStream(File.Create(destinationZipFilePath));
zipStream.SetLevel(6); // 压缩级别 0-9
CreateSingleZipFile(sourceFilePath, zipStream);
zipStream.Finish();
zipStream.Close();
}
//压缩单个文件
private static void CreateSingleZipFile(string sourceFile, ZipOutputStream zipStream)
{
Crc32 crc = new Crc32();
FileStream fileStream = File.OpenRead(sourceFile);
byte[] buffer = new byte[fileStream.Length];
fileStream.Read(buffer, 0, buffer.Length);
string tempFile = sourceFile.Substring(sourceFile.LastIndexOf("\\") + 1);
ZipEntry entry = new ZipEntry(tempFile);
entry.DateTime = DateTime.Now;
entry.Size = fileStream.Length;
fileStream.Close();
crc.Reset();
crc.Update(buffer);
entry.Crc = crc.Value;
zipStream.PutNextEntry(entry);
zipStream.Write(buffer, 0, buffer.Length);
}
/// <summary>
/// 递归压缩文件
/// </summary>
/// <param name="sourceFilePath">待压缩的文件或文件夹路径</param>
/// <param name="zipStream">打包结果的zip文件路径(类似 D:\WorkSpace\a.zip),全路径包括文件名和.zip扩展名</param>
/// <param name="staticFile"></param>
private static void CreateZipFiles(string sourceFilePath, ZipOutputStream zipStream)
{
Crc32 crc = new Crc32();
string[] filesArray = Directory.GetFileSystemEntries(sourceFilePath);
foreach (string file in filesArray)
{
if (Directory.Exists(file)) //如果当前是文件夹,递归
{
CreateZipFiles(file, zipStream);
}
else //如果是文件,开始压缩
{
FileStream fileStream = File.OpenRead(file);
byte[] buffer = new byte[fileStream.Length];
fileStream.Read(buffer, 0, buffer.Length);
string tempFile = file.Substring(sourceFilePath.LastIndexOf("\\") + 1);
ZipEntry entry = new ZipEntry(tempFile);
entry.DateTime = DateTime.Now;
entry.Size = fileStream.Length;
fileStream.Close();
crc.Reset();
crc.Update(buffer);
entry.Crc = crc.Value;
zipStream.PutNextEntry(entry);
zipStream.Write(buffer, 0, buffer.Length);
}
}
}
}