Как настроить строитель запросов для создания запроса просмотра событий на основе конкретного фильтра в C#?C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Как настроить строитель запросов для создания запроса просмотра событий на основе конкретного фильтра в C#?

Сообщение Anonymous »

Я хотел создать класс, в котором есть функция, которая представит информацию о просмотре событий. Итак, я использую класс EventLogquery, где мой код использует следующий раздел кода: < /p>

Код: Выделить всё

eventsQuery = new EventLogQuery(logName, PathType.LogName, eventquery);

Я использовал до * в Query EventQuery , у которого не было никаких проблем с ним. Однако, когда пользователь добавляет некоторые настройки фильтра, он всегда бросает ошибку, в которой говорится < /p>

Код: Выделить всё

"The specified query is invalid."

Я создал функцию, которая будет генерировать Query Care EventQuery для класса EventLogquery, а OutUT был следующим:

Код: Выделить всё

*[System[Provider[@Name='xxxxxxx' or @Name='xxxxxx'] and (Level=0  or Level=1 or Level=2 or Level=3 or Level=4) and TimeCreated[@SystemTime>='2025-03-14T09:48:11.173Z' and @SystemTime<='2025-03-28T09:48:11.173Z']]]

и, как упоминалось до упоминания, я получу ошибку «Указанный запрос недействителен.» . Итак, каков правильный синтаксис для раздела запроса, который будет использоваться в EventLogquery?

Код: Выделить всё

private string? QueryBuilder(object? parameters)
{
try
{
StringBuilder sb = new StringBuilder();
StringBuilder eventlevels = new StringBuilder();
StringBuilder providers = new StringBuilder();
sb.Append("*");

if (parameters != null)
{
var arr = (parameters as IEnumerable)?.Cast().ToList();
string? LogName = arr[0].ToString();
int? EventlogDateInterval = int.Parse((string)(arr[1]));
int? eventloglevel = int.Parse((string)(arr[2]));
string[]? EventSources = arr[3]?.ToString().Split(";");
string? eventErrorOnly = arr[4]?.ToString();

sb.Append("[System[");

if (EventSources != null)
{
string sourceQuery = "";

string[] eventSources = EventViewerSourceModel.EventSources[LogName].Split(";");

providers.Append("Provider[");

for (int i = 0; i < eventSources.Length; i++)
{
if (i == 0)
{
providers.Append($"@Name='{eventSources[i]}'");
}
else if (i == eventSources.Length - 1)
{
providers.Append($" or @Name='{eventSources[i]}']");
}
else
{
providers.Append($" or @Name='{eventSources[i]}'");
}
}

sourceQuery = providers.ToString();
sb.Append(sourceQuery);
}
if (eventloglevel != null)
{
sb.Append(" and ");
string levelquery = "";
//[(Level = 1  or Level = 2 or Level = 3 or Level = 4 or Level = 0 or Level = 5)]]
if (eventErrorOnly == "Y")
{
levelquery = "(Level=2)";
sb.Append(levelquery);
}
else if (eventloglevel > 1)
{
int loopcnt = 0;
var loglevels = Enum.GetValues(typeof(EventViewerLogLevel)).Cast().Where(e => (int)e  new { Name = e, Value = (int)e }).ToList();

foreach (var loglevel in loglevels)
{
if (loopcnt < 1)
{
eventlevels.Append($"(Level={loglevel.Value} ");
}
else if (loopcnt == loglevels.Count - 1)
{
eventlevels.Append($" or Level={loglevel.Value})");
}
else
{
eventlevels.Append($" or Level={loglevel.Value}");
}

loopcnt++;
}

levelquery = eventlevels.ToString();
sb.Append(levelquery);
}
else if (eventloglevel == 1)
{
levelquery = "(Level = 1)";
sb.Append(levelquery);
}
else if (eventloglevel > 5)
{
return null;
}
}
if (EventlogDateInterval != null)
{
sb.Append("  and ");
DateTime DateNow = DateTime.Now;
TimeSpan datetimeInterval = TimeSpan.FromDays(Convert.ToDouble(EventlogDateInterval));
DateTime StartTimeGenerated = DateNow.Subtract(datetimeInterval);

string isoDateNow = DateNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ");
string isoStartTimeGenerated = StartTimeGenerated.ToString("yyyy-MM-ddTHH:mm:ss.fffZ");

string timeQuery = $"TimeCreated[@SystemTime>='{isoStartTimeGenerated}' and @SystemTime<='{isoDateNow}']";
sb.Append(timeQuery);
}
}

sb.Append("]]");

return sb.ToString();
}
else
{
return sb.ToString();
}
}
catch (Exception ex)
{
return null;
}
}
< /code>
Для Eventlogsources я использую статический класс (EventViewerSourceModel.EventSources
), который удерживает источник и находится в словаре, где ключ является названием LogNam. Таким образом, чтобы захватить источники, это можно сделать в PowerShell, используя следующие сценарии, и каждый источник имеет; для их разделения друг от друга:

Код: Выделить всё

$logs = "Application", "System", "Security", "Setup"

foreach ($log in $logs) {
>>     Write-Output "Log: $log"
>>     Get-WinEvent -ListLog $log | Select-Object -ExpandProperty ProviderNames
>>     Write-Output "---------------------------------"
>> }
< /code>
Для уровней событий журнала, вот enum < /p>
    public enum EventViewerLogLevel
{
Info,
Critical,
Error,
Warning,
Information,
Verbose,
None
}
Лучше всего делать фильтрацию после получения результатов из *?

Подробнее здесь: https://stackoverflow.com/questions/795 ... specific-f
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»