Exchange Server’da Mesaj İzleme ve Log Analizi

Bir kullanıcı “mailim gitmedi” diye geldiğinde, ilk içgüdüsel tepki genellikle “spam klasörüne düşmüş olabilir” demek oluyor. Ama siz bir Exchange yöneticisiyseniz bu cevap sizi tatmin etmez. Nereye gitti, neden gitmedi, hangi sunucudan geçti, MTA’da ne oldu? Bunları bilmek zorundayız. Exchange’in mesaj izleme ve log altyapısı bu soruları cevaplamak için oldukça güçlü araçlar sunuyor; ancak bu araçları bilmeyenler için koskoca bir hazine kapalı kutuda bekliyor.

Mesaj İzlemenin Temeli: Message Tracking Log

Exchange Server, sunucudan geçen her mesaj için detaylı kayıtlar tutar. Bu kayıtlar Message Tracking Log olarak adlandırılır ve varsayılan olarak şu konumda bulunur:

C:Program FilesMicrosoftExchange ServerV15TransportRolesLogsMessageTracking

Bu dizini açtığınızda MSGTRK ile başlayan dosyalar göreceksiniz. Her dosya belirli bir zaman dilimine ait olup CSV formatındadır. Doğrudan notepad ile açabilirsiniz ama bu yöntem pek pratik değil. Asıl iş Exchange Management Shell (EMS) üzerinden yapılıyor.

Logların tutulma süresi varsayılan olarak 30 gün, maksimum boyut ise 1000 MB olarak ayarlıdır. Yoğun bir ortamda bu değerleri değiştirmeniz gerekebilir:

Set-TransportService -Identity "MAILSRV01" `
    -MessageTrackingLogMaxAge 60.00:00:00 `
    -MessageTrackingLogMaxDirectorySize 5GB `
    -MessageTrackingLogMaxFileSize 50MB

Değişikliği doğrulamak için:

Get-TransportService "MAILSRV01" | Select-Object MessageTrackingLog*

Get-MessageTrackingLog: Temel Silahınız

Exchange’de mesaj izlemenin kalbi Get-MessageTrackingLog cmdlet’idir. Basit görünür ama parametreleri doğru kullandığınızda inanılmaz derecede etkili hale gelir.

Temel kullanım:

Get-MessageTrackingLog -Server MAILSRV01 `
    -Start "01/15/2024 08:00:00" `
    -End "01/15/2024 18:00:00" `
    -Sender "[email protected]" `
    -ResultSize Unlimited

Önemli parametreler şunlar:

  • -Server: Hangi Exchange sunucusunda arama yapılacağını belirtir
  • -Start / -End: Zaman aralığı, bu iki parametreyi her zaman kullanın aksi halde sonuçlar çok geniş gelir
  • -Sender: Gönderen adresine göre filtreler
  • -Recipients: Alıcı adresine göre filtreler, dizi olarak birden fazla alıcı verebilirsiniz
  • -MessageSubject: Konu satırına göre arama yapar, büyük/küçük harf duyarsızdır
  • -EventId: RECEIVE, DELIVER, SEND, FAIL, RESOLVE gibi olay türlerine göre filtreler
  • -MessageId: Mesajın benzersiz Message-ID değerine göre arama yapar
  • -ResultSize: Varsayılan 1000 sonuç döner, büyük ortamlarda “Unlimited” kullanın

Gerçek Senaryo: Gönderilemeyen Mesajı İzlemek

Diyelim ki muhasebe müdürü Selin Hanım saat 10:15’te bir e-posta göndermiş ama karşı taraf almamış. Önce gönderimi doğrulayalım:

Get-MessageTrackingLog -Server MAILSRV01 `
    -Start "01/15/2024 10:00:00" `
    -End "01/15/2024 11:00:00" `
    -Sender "[email protected]" `
    -ResultSize Unlimited | 
    Select-Object Timestamp, EventId, Source, Recipients, MessageSubject, TotalBytes |
    Format-Table -AutoSize

Çıktıda EventId sütununa bakıyorsunuz. Sağlıklı bir e-posta yolculuğunda şu olayları görmeniz gerekir:

  • RECEIVE: Mesaj sunucuya ulaştı
  • RESOLVE: Alıcı adresi çözümlendi
  • TRANSFER: Başka bir sunucuya iletildi (Hub/Edge senaryoları)
  • SEND: Harici sunucuya gönderildi
  • DELIVER: Posta kutusuna teslim edildi

Eğer FAIL veya DSN görüyorsanız bir şeyler ters gitmiş demektir. Detaya inmek için:

Get-MessageTrackingLog -Server MAILSRV01 `
    -Start "01/15/2024 10:00:00" `
    -End "01/15/2024 11:00:00" `
    -Sender "[email protected]" `
    -EventId "FAIL" |
    Select-Object Timestamp, Recipients, Source, SourceContext, EventData |
    Format-List

EventData alanı size genellikle hata kodunu ve açıklamasını verir. “550 5.1.1 User unknown” görüyorsanız alıcı adresi yanlış, “421 4.3.2 Service not available” görüyorsanız karşı sunucuda sorun var demektir.

EAC Üzerinden Mesaj İzleme

Her şeyi Shell’den yapmak zorunda değilsiniz. Exchange Admin Center üzerinden de mesaj izleyebilirsiniz:

Mail flow > Message trace yolunu izleyin. Burada tarih aralığı, gönderen, alıcı gibi filtreleri GUI üzerinden ayarlayabilirsiniz. Özellikle teknik olmayan yöneticilere raporlama yapacaksanız EAC çok daha pratik.

Ancak EAC’ın bir kısıtlaması var: 48 saatten eski sorgular için “Summary report” döner, detaylı log göremezsiniz. Geriye dönük 30 güne kadar olan veriler için “Enhanced summary” veya CSV export kullanmanız gerekir.

Protocol Log Analizi: SMTP’nin Derinlerine İnmek

Mesaj takip logu size yüksek seviyeli bilgi verir. Ama bazen SMTP konuşmasının ta kendisine bakmanız gerekir. İşte burada Protocol Log devreye giriyor.

Send Connector ve Receive Connector’lar için ayrı ayrı protokol logları tutulur. Varsayılan konumları:

C:Program FilesMicrosoftExchange ServerV15TransportRolesLogsFrontEndProtocolLogSmtpReceive
C:Program FilesMicrosoftExchange ServerV15TransportRolesLogsFrontEndProtocolLogSmtpSend

Protocol logging varsayılan olarak Send Connector’larda kapalı, Receive Connector’larda açık olabilir. Kontrol etmek için:

# Send Connector'ların log durumunu kontrol et
Get-SendConnector | Select-Object Name, ProtocolLoggingLevel

# Receive Connector'ların log durumunu kontrol et
Get-ReceiveConnector -Server MAILSRV01 | Select-Object Name, ProtocolLoggingLevel

Bir Send Connector için protokol loglamayı açmak:

Set-SendConnector "Internet Send Connector" -ProtocolLoggingLevel Verbose

Protocol log dosyaları düz metin formatındadır ve her satır bir SMTP komutunu veya yanıtını temsil eder. Tipik bir akış şöyle görünür:

EHLO mailsrv01.sirket.com.tr
250-mail.hedef.com Hello
250-SIZE 52428800
250 AUTH LOGIN PLAIN
MAIL FROM:<[email protected]>
250 2.1.0 Ok
RCPT TO:<[email protected]>
550 5.1.1 The email account that you tried to reach does not exist

Bu logu PowerShell ile parse etmek istiyorsanız:

$logPath = "C:Program FilesMicrosoftExchange ServerV15TransportRolesLogsFrontEndProtocolLogSmtpSend"
$today = Get-Date -Format "yyyyMMdd"

Get-Content "$logPathSEND$today*.log" | 
    Where-Object { $_ -notlike "#*" } |  # Yorum satırlarını atla
    Where-Object { $_ -match "550|421|554" } |  # Hata kodlarını filtrele
    Select-Object -Last 50

Connectivity Log: Bağlantı Sorunlarını Tespit Etmek

Bir sonraki seviye Connectivity Log. Bu loglar, Transport servisinin diğer sunucularla kurduğu bağlantıları kayıt altına alır. Özellikle “mesaj kuyrukta bekliyor ama gitmiyor” durumlarında bu loglara bakmanız gerekir.

# Connectivity log ayarlarını görüntüle
Get-TransportService MAILSRV01 | Select-Object ConnectivityLog*

# Log konumunu değiştirmek için
Set-TransportService MAILSRV01 `
    -ConnectivityLogPath "D:ExchangeLogsConnectivity" `
    -ConnectivityLogMaxAge 30.00:00:00

Connectivity logları şu formatta bilgi içerir: bağlantı zamanı, yerel endpoint, uzak endpoint, bağlantı süresi, gönderilen/alınan mesaj sayısı, ve bağlantı sonucu. Bir hedefe ulaşıp ulaşamadığınızı bu logdan net görürsünüz.

Kuyruk Yönetimi ve Log İlişkisi

Mesaj izleme logları ile kuyruk yönetimini birlikte kullanmak güçlü bir tanı aracı oluşturur. Önce mevcut kuyruklara bakın:

Get-Queue -Server MAILSRV01 | 
    Where-Object { $_.MessageCount -gt 0 } |
    Sort-Object MessageCount -Descending |
    Select-Object Identity, Status, MessageCount, NextHopDomain, LastError

Bir kuyruğun içindeki mesajlara bakmak için:

Get-Message -Queue "MAILSRV01Internet Send Connectorhedef.com" |
    Select-Object FromAddress, Recipients, Subject, DateReceived, Status |
    Format-Table -AutoSize

Kuyruktaki bir mesajın MessageId’sini alıp tracking logda aramak:

$msgId = (Get-Message -Queue "MAILSRV01Internethedef.com" | Select-Object -First 1).InternetMessageId

Get-MessageTrackingLog -Server MAILSRV01 `
    -MessageId $msgId `
    -Start (Get-Date).AddDays(-1) `
    -End (Get-Date) |
    Select-Object Timestamp, EventId, Source, EventData |
    Format-List

Toplu Analiz: Raporlama Senaryoları

Günlük operasyonel kontroller için bazı hazır script parçaları işinizi kolaylaştırır.

Son 24 saatte en çok mail gönderen kullanıcıları bulmak:

$start = (Get-Date).AddHours(-24)
$end = Get-Date

Get-MessageTrackingLog -Server MAILSRV01 `
    -Start $start `
    -End $end `
    -EventId "RECEIVE" `
    -ResultSize Unlimited |
    Where-Object { $_.Source -eq "STOREDRIVER" } |
    Group-Object Sender |
    Sort-Object Count -Descending |
    Select-Object -First 20 Name, Count |
    Format-Table -AutoSize

Son 1 saatte başarısız olan gönderimler:

Get-MessageTrackingLog -Server MAILSRV01 `
    -Start (Get-Date).AddHours(-1) `
    -End (Get-Date) `
    -EventId "FAIL" `
    -ResultSize Unlimited |
    Select-Object Timestamp, Sender, Recipients, EventData |
    Export-Csv -Path "C:ReportsFailedMessages_$(Get-Date -Format 'yyyyMMddHHmm').csv" `
    -NoTypeInformation -Encoding UTF8

Belirli bir domain’e giden tüm mailleri listelemek:

Get-MessageTrackingLog -Server MAILSRV01 `
    -Start "01/01/2024 00:00:00" `
    -End "01/31/2024 23:59:59" `
    -EventId "SEND" `
    -ResultSize Unlimited |
    Where-Object { $_.Recipients -like "*@hedef-domain.com" } |
    Select-Object Timestamp, Sender, Recipients, MessageSubject, TotalBytes |
    Sort-Object Timestamp |
    Export-Csv -Path "C:ReportsHedefDomainMails.csv" -NoTypeInformation -Encoding UTF8

Güvenlik Odaklı Log Analizi

Exchange logları sadece operasyonel sorun giderme için değil, güvenlik analizi için de kritik. Bir kullanıcı hesabının ele geçirilip geçirilmediğini ya da içeriden veri sızıntısı olup olmadığını araştırırken şu sorguyu kullanıyorum:

# Bir kullanıcının olağandışı saatlerde mail gönderip göndermediğini kontrol et
Get-MessageTrackingLog -Server MAILSRV01 `
    -Start (Get-Date).AddDays(-7) `
    -End (Get-Date) `
    -Sender "[email protected]" `
    -EventId "RECEIVE" `
    -ResultSize Unlimited |
    Where-Object { 
        ($_.Timestamp.Hour -lt 7 -or $_.Timestamp.Hour -gt 20) -and
        $_.Recipients -notlike "*@sirket.com.tr"
    } |
    Select-Object Timestamp, Recipients, MessageSubject, TotalBytes |
    Format-Table -AutoSize

Bu sorgu mesai saatleri dışında dışarıya gönderilmiş mailleri listeler. Sonuçta beklenmedik bir şey görürseniz detaylı incelemeye geçebilirsiniz.

Log Rotasyonu ve Arşivleme

Production ortamında log yönetimini es geçmek ileride ciddi sorunlara yol açar. Özellikle yüksek hacimli ortamlarda disk dolabilir ve Exchange servisi durabilir. Basit bir monitoring scripti:

$logDirs = @(
    "C:Program FilesMicrosoftExchange ServerV15TransportRolesLogsMessageTracking",
    "C:Program FilesMicrosoftExchange ServerV15TransportRolesLogsFrontEndProtocolLogSmtpReceive",
    "C:Program FilesMicrosoftExchange ServerV15TransportRolesLogsFrontEndProtocolLogSmtpSend"
)

foreach ($dir in $logDirs) {
    $size = (Get-ChildItem $dir -Recurse -ErrorAction SilentlyContinue | 
             Measure-Object -Property Length -Sum).Sum / 1GB
    
    Write-Host "$dir -> $([Math]::Round($size, 2)) GB" -ForegroundColor $(
        if ($size -gt 5) { "Red" } 
        elseif ($size -gt 3) { "Yellow" } 
        else { "Green" }
    )
}

Bu scripti Task Scheduler ile günlük çalıştırıp sonuçları mail olarak kendinize gönderin. Kritik eşik aşıldığında habersiz kalmazsınız.

Sık Karşılaşılan Sorunlar ve Çözümleri

“Get-MessageTrackingLog çok yavaş çalışıyor” diyorsanız, büyük ihtimalle -Start ve -End parametreleri olmadan çalıştırıyorsunuz. Her zaman zaman aralığı belirtin. Ayrıca ResultSize’ı Unlimited yerine belirli bir sayıyla sınırlandırarak test yapın.

“EventId FAIL görüyorum ama sebep belli değil” durumunda EventData yetersiz kalabilir. Bu durumda Protocol Log’a geçin ve aynı zaman damgasına ait SMTP konuşmasını bulun. Orada çok daha açık hata mesajları göreceksiniz.

“Mesaj tracking logda görünüyor ama kullanıcı almadım diyor” senaryosunda, DELIVER eventi var mı kontrol edin. DELIVER varsa mesaj posta kutusuna düşmüş demektir. Bu durumda sorun Outlook tarafında arama yapılması gerekiyor: silinmiş öğeler, spam filtresi, Outlook kuralları.

“DAG ortamında hangi sunucuda arama yapacağımı bilmiyorum” için tüm DAG üyelerinde paralel arama yapabilirsiniz:

$dagMembers = Get-DatabaseAvailabilityGroup "DAG01" | 
              Select-Object -ExpandProperty Servers

foreach ($server in $dagMembers) {
    Write-Host "=== $server ===" -ForegroundColor Cyan
    Get-MessageTrackingLog -Server $server `
        -Start (Get-Date).AddHours(-2) `
        -End (Get-Date) `
        -Sender "[email protected]" `
        -ResultSize 100 |
        Select-Object Timestamp, EventId, Recipients
}

Sonuç

Exchange mesaj izleme ve log analizi, bir posta yöneticisinin günlük hayatının kaçınılmaz bir parçası. Önemli olan, doğru araçlara ulaşmayı bilmek ve olayı sistematik bir şekilde araştırmak. Message Tracking Log size yüksek seviyeli akışı gösterir, Protocol Log SMTP diyaloğunun tamamını verir, Connectivity Log ise ağ katmanındaki sorunları gün yüzüne çıkarır. Bu üç katmanı birlikte kullanmayı öğrendiğinizde, “mailin nereye gittiği” sorusuna çoğu zaman birkaç dakika içinde yanıt verebilir hale gelirsiniz.

Son bir not: Bu logları sadece sorun çıktığında değil, proaktif olarak da izleyin. Anormalileri önceden yakalamak, hem güvenlik hem de operasyonel süreklilik açısından sizi her zaman bir adım önde tutar. Haftalık bir “mail flow sağlık kontrolü” rutini oluşturmak, uzun vadede size sayısız baş ağrısından kurtaracaktır.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir