Централизованное чтение логов в Windows

Журналы Windows

Ранее уже было написано у меня о сборе логов с различных серверов и хранения их в единой БД. Сегодня будет заметка для сбора логов.

Софт и настройка

Логи нужно собирать, в первую очередь, с серверов, так что это достаточно важная задача. А вот чем собирать — вопрос. Можно отправлять файлы на сервер и там их парсить и анализировать. Можно поставить специальный софт, который сам это будет делать и отправлять на сервер готовые записи (этот больше подходит, так как удобнее). Теперь сам софт.

Я лично попробовал 2 программы: eventlog-to-syslog и nxlog. Первый был обновлен в 2013 году и отправляет на сервер логи в формате syslog, но то что он «пихает» все что можно в виде строки, в дальнейшем тяжело парсить. В итоге получается ну очень длинное регулярное выражение, в котором можно легко запутаться. Вторая софтина есть в 3х вариантах: Enterprise Edition, Manager и Community Edition. Первый вариант для корпоративных клиентов (платная), вторая для сообщества (бесплатная). В Community Edition есть ряд ограничений, но мне этого хватает: получение событий, преобразование в JSON, отправка на удаленный сервер по TCP и UDP.

Регистрируемся на сайте и скачиваем файл для винды. В итоге устанавливаем msi-файл. Далее по пути C:\Program Files\nxlog\conf\ (если не меняли стандартный путь) и файл nxlog.conf приводим к следующему виду:


<Extension _syslog>
    Module      xm_syslog
</Extension>

<Extension _charconv>
    Module      xm_charconv
    AutodetectCharsets iso8859-2, utf-8, utf-16, utf-32
</Extension>

<Extension _exec>
    Module      xm_exec
</Extension>

<Extension _fileop>
    Module      xm_fileop

    # Check the size of our log file hourly, rotate if larger than 5MB
    <Schedule>
        Every   1 hour
        Exec    if (file_exists('%LOGFILE%') and \
                   (file_size('%LOGFILE%') >= 5M)) \
                    file_cycle('%LOGFILE%', 8);
    </Schedule>

    # Rotate our log file every week on Sunday at midnight
    <Schedule>
        When    @weekly
        Exec    if file_exists('%LOGFILE%') file_cycle('%LOGFILE%', 8);
    </Schedule>
</Extension>

<Extension json>
    Module    xm_json
</Extension>

<Input eventlog>
    Module    im_msvistalog
    Exec      to_json();
</Input>

# Snare compatible example configuration
# Collecting event log
# <Input in>
#     Module      im_msvistalog
# </Input>
# 
# Converting events to Snare format and sending them out over TCP syslog
# <Output out>
#     Module      om_tcp
#     Host        192.168.1.1
#     Port        514
#     Exec        to_syslog_snare();
# </Output>
# 
# Connect input 'in' to output 'out'
# <Route 1>
#     Path        in => out
# </Route>

<Output udp>
    Module    om_udp
    Host      ip-адрес_сервера
    Port      5517
</Output>

<Route eventlog_to_network>
    Path        eventlog => udp
</Route>




Я специально оставил стандартные тэги из оригинального файла, чтобы было проще и наглядней искать и ориентироваться в нем.

На сервере

Собирает у нас эти логи все тот же fluentd (winlog.conf):


<source>
  @type udp
  tag winlog
  <parse>
    @type json
  </parse>
  port 5517
  bind 0.0.0.0
  message_length_limit 10MB
</source>

<filter winlog.**>
    @type record_modifier
    <record>
        EventTimeMillis ${time.nsec}
    </record>
</filter>

<match winlog.**>
  @type http
  open_timeout 2
  endpoint http://clickhouse:port/?user=login&password=password&database=logs&query=INSERT%20INTO%20winlog%20FORMAT%20JSONEachRow
  <format>
    @type json
  </format>
  json_array true
  <buffer>
    flush_interval 10s
  </buffer>
</match>




На забываем добавить строчку @include conf.d/winlog.conf в основной конфиг.

БД

Я думал ClickHouse меня пошлет на поляну одуванчики собирать, но пока что все обошлось:


CREATE TABLE IF NOT EXISTS logs.winlog (
EventTime DateTime,
EventTimeMillis UInt64,
Hostname String default 'unknow',
Keywords Nullable(Int64),
EventType Nullable(String),
SeverityValue Nullable(Int16),
Severity Nullable(String),
EventID Nullable(Int32),
SourceName Nullable(String),
ProviderGuid Nullable(String),
Version Nullable(Int32),
Task Nullable(Int32),
OpcodeValue Nullable(Int32),
RecordNumber Nullable(Int64),
ActivityID Nullable(String),
CallerPID Nullable(String),
ProcessID Nullable(Int32),
ThreadID Nullable(Int32),
Channel Nullable(String),
SChannelName Nullable(String),
SChannelType Nullable(String),
Domain Nullable(String),
AccountName Nullable(String),
UserID Nullable(String),
UserName Nullable(String),
DomainName Nullable(String),
WorkstationName Nullable(String),
SessionId Nullable(String),
LogonGuid Nullable(String),
VolumeGuid Nullable(String),
VolumeNameLength Nullable(String),
VolumeName Nullable(String),
VolumeLabelLength Nullable(String),
VolumeLabel Nullable(String),
Error Nullable(String),
TransmittedServices Nullable(String),
AccountType Nullable(String),
Message Nullable(String),
Category Nullable(String),
TicketOptions Nullable(String),
Opcode Nullable(String),
CSEElaspedTimeInMilliSeconds Nullable(String),
ErrorCode Nullable(String),
CSEExtensionName Nullable(String),
CSEExtensionId Nullable(String),
operationName Nullable(String),
OperationDescription Nullable(String),
OperationElaspedTimeInMilliSeconds Nullable(String),
PolicyActivityId Nullable(String),
PolicyApplicationMode Nullable(String),
PolicyDownloadTimeElapsedInMilliseconds Nullable(String),
PrincipalSamName Nullable(String),
IsMachine Nullable(String),
IsDomainJoined Nullable(String),
IsBackgroundProcessing Nullable(String),
IsAsyncProcessing Nullable(String),
IsServiceRestart Nullable(String),
ReasonForSyncProcessing Nullable(String),
Profiles Nullable(String),
SettingType Nullable(String),
SettingValueSize Nullable(String),
SettingValue Nullable(String),
SettingValueString Nullable(String),
Origin Nullable(String),
ModifyingUser Nullable(String),
ModifyingApplication Nullable(String),
Environment Nullable(String),
EventsUploaded Nullable(String),
EventsDropped Nullable(String),
LastEventlogWrittenTime Nullable(String),
PackageName Nullable(String),
TargetUserName Nullable(String),
TargetSid Nullable(String),
TargetDomainName Nullable(String),
ServiceName Nullable(String),
ServiceSid Nullable(String),
serviceStatus Nullable(String),
Workstation Nullable(String),
Status Nullable(String),
TicketEncryptionType Nullable(String),
PreAuthType Nullable(String),
IpAddress Nullable(String),
IpPort Nullable(String),
PortNumber Nullable(String),
PathID Nullable(String),
TargetID Nullable(String),
LUN Nullable(String),
ClassDeviceGuid Nullable(String),
AdapterGuid Nullable(String),
BusType Nullable(String),
MiniportName Nullable(String),
VendorId Nullable(String),
ProductId Nullable(String),
RequestDuration_ms Nullable(String),
WaitDuration_ms Nullable(String),
Command Nullable(String),
SrbStatus Nullable(String),
ScsiStatus Nullable(String),
SenseKey Nullable(String),
AddSense Nullable(String),
AddSenseQ Nullable(String),
IoSize Nullable(String),
QueueDepth Nullable(String),
LBA Nullable(String),
TaskInstanceId Nullable(String),
EnginePID Nullable(String),
LogString Nullable(String),
SubjectUserSid  Nullable(String),
SubjectUserName Nullable(String),
SubjectDomainName Nullable(String),
SubjectLogonId Nullable(String),
ObjectServer Nullable(String),
ObjectType Nullable(String),
ObjectName Nullable(String),
HandleId Nullable(String),
TransactionId Nullable(String),
AccessList Nullable(String),
AccessMask Nullable(String),
PrivilegeList Nullable(String),
ProcessName Nullable(String),
ResourceAttributes Nullable(String),
param1 Nullable(String),
param2 Nullable(String),
param3 Nullable(String),
param4 Nullable(String),
param5 Nullable(String),
ClientLUID Nullable(String),
ClientUserName Nullable(String),
resourceUri Nullable(String),
SMBShare Nullable(String),
Vcb Nullable(String),
ClientDomainName Nullable(String),
TaskName Nullable(String),
MechanismOID Nullable(String),
OldSd Nullable(String),
Reason Nullable(String),
InstanceId Nullable(String),
IsExtensionAsyncProcessing Nullable(String),
exception Nullable(String),
VolumeCorrelationId Nullable(String),
DfsNamespace Nullable(String),
NewSd Nullable(String),
InfoDescription Nullable(String),
SyncFromPDC Nullable(String),
Type Nullable(String),
Path Nullable(String),
Priority Nullable(String),
RefreshTriggerSource Nullable(String),
SyncType Nullable(String),
SamAccountName Nullable(String),
Parameter Nullable(String),
hrError Nullable(String),
SidHistory Nullable(String),
DCName Nullable(String),
DCIPAddress Nullable(String),
TimeConsumedInMilliSeconds Nullable(String),
Machines Nullable(String),
Dummy Nullable(String),
DisplayName Nullable(String),
DCDiscoveryTimeInMilliSeconds Nullable(String),
UserNameLength Nullable(String),
UserPrincipalName Nullable(String),
MachineRole Nullable(String),
ID Nullable(String),
UserContext Nullable(String),
DeviceGUID Nullable(String),
CallerProcessId Nullable(String),
CallerProcessName Nullable(String),
PrincipalCNName Nullable(String),
PrincipalDomainName Nullable(String),
DCDomainName Nullable(String),
serverName Nullable(String),
namespaceName Nullable(String),
wmiClassName Nullable(String),
methodName Nullable(String),
protocol Nullable(String),
Name Nullable(String),
DeviceNameLength Nullable(String),
LowestFreeSpaceInBytes Nullable(String),
IsBootVolume Nullable(String),
ActionName Nullable(String),
FolderId Nullable(String),
HighIoLatencyCount Nullable(String),
IntervalDurationUs Nullable(String),
NCReadIOCount Nullable(String),
NCReadTotalBytes Nullable(String),
NCReadAvgLatencyNs Nullable(String),
NCWriteIOCount Nullable(String),
NCWriteTotalBytes Nullable(String),
NCWriteAvgLatencyNs Nullable(String),
FileFlushCount Nullable(String),
FileFlushAvgLatencyNs Nullable(String),
VolumeFlushCount Nullable(String),
VolumeFlushAvgLatencyNs Nullable(String),
FileLevelTrimCount Nullable(String),
FileLevelTrimTotalBytes Nullable(String),
FileLevelTrimExtentsCount Nullable(String),
FileLevelTrimAvgLatencyNs Nullable(String),
VolumeTrimCount Nullable(String),
VolumeTrimTotalBytes Nullable(String),
VolumeTrimExtentsCount Nullable(String),
VolumeTrimAvgLatencyNs Nullable(String),
IoBucketsCount Nullable(String),
TotalBytesBucketsCount Nullable(String),
ExtentsBucketsCount Nullable(String),
IoCount Nullable(String),
TotalLatencyUs Nullable(String),
TotalBytes Nullable(String),
TrimExtentsCount Nullable(String),
IoTypeIndex Nullable(String),
ServerNameLength Nullable(String),
ServerName Nullable(String),
AllNtpServers Nullable(String),
TickCount Nullable(String),
IFTSTMP Nullable(String),
GPOList Nullable(String),
XPath Nullable(String),
LastError Nullable(String),
PolicyProcessingMode Nullable(String),
ResultCode Nullable(String),
BandwidthInkbps Nullable(String),
ComputerAccountChange Nullable(String),
HomeDirectory Nullable(String),
HomePath Nullable(String),
ScriptPath Nullable(String),
ProfilePath Nullable(String),
UserWorkstations Nullable(String),
PasswordLastSet Nullable(String),
AccountExpires Nullable(String),
PrimaryGroupId Nullable(String),
AllowedToDelegateTo Nullable(String),
OldUacValue Nullable(String),
NewUacValue Nullable(String),
UserAccountControl Nullable(String),
UserParameters Nullable(String),
LogonHours Nullable(String),
DnsHostName Nullable(String),
ServicePrincipalNames Nullable(String),
IsSlowLink Nullable(String),
ThresholdInkbps Nullable(String),
LinkDescription Nullable(String),
NumberOfGPOsDownloaded Nullable(String),
NumberOfGPOsApplicable Nullable(String),
GPODownloadTimeElapsedInMilliseconds Nullable(String),
DescriptionString Nullable(String),
GPOInfoList Nullable(String),
IsGPOListChanged Nullable(String),
GPOListStatusString Nullable(String),
ApplicableGPOList Nullable(String),
DeviceName Nullable(String),
PolicyElaspedTimeInSeconds Nullable(String),
IsConnectivityFailure Nullable(String),
NextPolicyApplicationTime Nullable(String),
NextPolicyApplicationTimeUnit Nullable(String),
EventReceivedTime Nullable(DateTime),
SourceModuleName Nullable(String),
SourceModuleType Nullable(String)
)
ENGINE = ReplacingMergeTree() PARTITION BY toDate(EventTime)
ORDER BY (EventTime, EventTimeMillis, Hostname)
TTL EventTime + toIntervalMonth(6)
SETTINGS index_granularity = 8192;




Да, такая таблица получилась. Дальше только анализировать в различных инструментах.

Заключение

Собственно это все. После сбора определенного количества логов можно приступать к анализу деятельности узла, которое и хотим отслеживать. Судя по структуре так же можно в дальнейшем дела корреляцию между узлами, например, чтение файлов на файл-сервере и клиенте, который запрашивает этот файл и т.д.

Поделиться
Вы можете оставить комментарий, или ссылку на Ваш сайт.

Оставить комментарий

Вы должны быть авторизованы, чтобы разместить комментарий.