Özet:
Log dosyalarını, dizin yapısını veya text dosyalarını hızlı taramanın yolları Microsoftun Log Parser aracıyla, artık SQL dil yapısı ile log dosyalarını rahatlıkla sorgulayabilirsiniz.
Gerekli Araçlar
Giriş:
Genellikle çok yoğun hit alan sitelerde log raporları almak, zaman alıcı bir iştir. Web sitelerinde rapor almak için genellikle WebTrends adlı program kullanılır. Bu uygulama bir hayli detaylı rapor üretebilmektedir. Ancak problem, özel bir rapor alınmak istendiğinde ortaya çıkar. Örneğin adres satırında geçen bir değer, özel bir anlam ifade edebilir ve bunun sorgulanması istenebilir. Webtrends bu gibi işlerde zayıf kalmaktadır.
Alternatif olarak IISin, log bilgilerini SQL veritabanına yazması sağlanabilir. Ancak bu da, zamana yayılsa bile, SQL serverın yorulmasına, zaten çok büyük olan log bilgilerinin gereksiz yere veritabanını şişirmesine sebep olur.
Geçenlerde, bir sitenin log dosyalarının incelenip, duruma özel bir rapor oluşturulması istendi. Sistemde 5 adet IIS, hergün yaklaşık 2GBlık log dosyası oluşturuyordu. Her log dosyasında da yaklaşık 500,000 satır vardı. Log dosyaları her gece özel bir makinaya taşınıp, her makina için ayrı bir dizine kopyalanıyordu. İlk önce .Net ile bir program yazıp satırların tek tek sorgulanarak raporun üretilmesini düşündüm. Sonuç çok yavaştı uygulanabilirdi, ama çözüm daha hızlı olmalıydı. Ayrıca daha çok geliştirme zamanına ihtiyaç vardı. Veritabanı çözümünü düşünmedim bile, yer sorunu ve indeksleme olmadan hızlı sorgulama yapmak, problemi sadece değişik boyutlara taşıyordu. Çözüm Log Parserla geldi. İnceleyince, çok enteresan bir uygulama ve çok performanslı çalışıyor. Bahsi geçen log dosyalarını bu uygulama sayesinde 2-3 dakika içinde tarayabildim.
Log Parserı indirip kurduğunuzda, dizine iki farklı uygulama kurar biri "LogParser.dll" diğeri de "LogParser.exe". Tahmin edeceğiniz üzere biri komut satırından çalıştırılabilir uygulama, diğeri de bir ActiveX nesnesi. Exe versiyonu komut satırından çalıştırıp çabuk sorgulamalar yapmanızı sağlıyor. Eski günlerdeki gibi, batch dosyalarıyla uğraşmayı severseniz veya test amaçlı kullanmak için iyi bir çözüm. Esas güç ise ActiveX versiyonunda geliyor Uygulama, kurulum sırasında kendisini "MS Utility 1.0 Type Library - LogParser Interfaces collection" olarak register ediyor. Bu noktada uygulamaya ActiveX nesnesi olarak erişebildiğiniz için istediğiniz gibi programlayabiliyorsunuz. Dilerseniz VBScript ile, dilerseniz VB ile, dilerseniz JScript ile, dilerseniz Interop sayesinde .Net ile program yazabiliyorsunuz. Script dillerinde LogParser Nesnesi yaratabilmek için gereken ProgId; "MSUtil.LogQuery".
Aşağıdaki örnekleri kullanabilmek için, http://www.microsoft.com/technet/community/scriptcenter/logs/logparser/default.mspx adresinden Log Parser 2.0 uygulamasını indirip kurmanız gerekiyor. Uygulama kurulduktan sonra, LogParser.exe dosyasını "\Program Files" klasörünün altında "Log Parser" dizininde bulabilirsiniz.
LogParserı komut satırında kullanmak (LogParser.exe):
LogParser ile en basitinden şöyle bir ifade yazmak mümkün (ex040412.log dosyasının aynı dizinde olduğunu var sayarak);
LogParser "SELECT top 4 sc-status, cs-uri-stem FROM ex040412.log"
sonuçta aşağıdaki gibi bir sonuç geliyor.
sc-status cs-uri-stem --------- --------------------------------- 200 /SSO/vs-72742184429620088_tmp.htm 200 /_vti_inf.html 404 /SSO/_vti_bin/shtml.dll/_vti_rpc 200 /_vti_inf.html 200 /_vti_bin/shtml.dll/_vti_rpc Statistics: ----------- Elements processed: 5 Elements output: 5 Execution time: 0.05 seconds
Bu ifade yerine;
LogParser "SELECT * FROM <1>"
yazarsanız, IISteki ilk aplikasyonun bütün log dosyalarındaki, tüm kayıtların, tüm alanlarını seçersiniz. Örneğin sitede olmayan sayfaları bulmak için;
LogParser "SELECT * FROM <1> WHERE sc-status=404"
şeklinde bir ifade yazabilirsiniz.
LogParserı .Net ile kullanmak (LogParser.dll):
LogParser.dll, kullanıcıya ADOya çok benzeyen bir arayüz sunmaktadır. Fakat fiziksel olarak ADO ile uzaktan yakından ilgisi yoktur. C# ile bir konsol uygulaması yazalım. Amacımızın başarılı gösterilen sayfaları listelemek olduğunu varsayalım. (İpucu: log dosyasında "sc-status" değeri 200 ise bu sayfa başarıyla gösterilmiş demektir. "cs-uri-stem" alanı ise bize sayfa adını verir). İlk olarak Proje oluşturalım;
Koddaki en üstteki "using System;" satırının altına "using MSUtil;" satırını ekleyelim.
using System; using MSUtil;
LogParser.dll içinde LogQuery sınıfını barındırır. Bu sınıf LogParser.exenin nesne halidir. Artık Main metodunun içini yazmaya başlayabiliriz. Main metodunu aşağıdaki şekilde değiştirin; [STAThread] static void Main(string [] args) {
ILogQuery logQuery = new LogQueryClassClass(); ILogRecordset recordSet; ILogRecord record; recordSet = logQuery.Execute("select cs-uri-stem from <1> where sc-status=200", null); for(; !recordSet.atEnd(); recordSet.moveNext()) { record=recordSet.getRecord(); string val = record.getValue(0).ToString(); Console.WriteLine(val); } recordSet.close();
ILogQuery logQuery = new LogQueryClassClass(); ILogRecordset recordSet; ILogRecord record;
recordSet = logQuery.Execute("select cs-uri-stem from <1> where sc-status=200", null); for(; !recordSet.atEnd(); recordSet.moveNext()) {
record=recordSet.getRecord(); string val = record.getValue(0).ToString(); Console.WriteLine(val);
} recordSet.close();
}
Kodu F5 tuşuna basarak çalıştırdığınızda, eğer daha önce IISte bir şeyler yapmışsanız, uzun bir çıktısı olacaktır.
Kodda üç adet değişken tanımladık;
İlk iş olarak logQuery değişkeninin Execute metodu çağrılıyor ve sonuç recordSet değişkenine atanıyor. Bu metod iki parametre alır. İlki bir SQL ifadesi, diğeri de logun okunacağı girdi tipini belirtir, biz bu değere, SQL ifadesinin FROM kısmından belirlensin diye null atadık. Bu parametre hakkında daha detaylı bilgiyi uygulamayla gelen Word dokümanında bulabilirsiniz. Execute metodu hemen çalışmaz, sadece sorguyu hazırlar ve dosya imlecini uygun yere getirir. Esas işlem recordSetin moveNext metodunda yapılır. Bu metod belirlenen şartlara uygun bir sonraki satırı bulur ve kayıt içeriğini hazırlar. recordSetin atEnd metodu ise dosyanın sonuna gelinip gelinmediğini gösterir. Böylece çok rahat bir şekilde log dosyası içinde, ileriye doğru hareket etmemiz sağlanır. Bu döngünün içinde record değişkenine, recordSetin getRecord metodu çağrılarak kayıt (satır) bilgisi alınır. recordun da getValue adlı bir metdou vardır. Bu metod bir int değeri alır ve uygun alan değerini döndürür. Böylece bir recordSetteki recordun herhangi bir alanının değeri okunabilir. Bizim uygulamamız sadece bu değeri ekrana yazıyor. recordSeti de dosya sonuna geldiğinde de kapatıyor.
Özellikler:
Şu ana kadar LogParserin kullanımını gördük. Biraz desteklenen SQL özelliklerinden bahsetmek gerek. Uygulama sadece SELECT ifadesini destekliyor, yani INSERT, UPDATE veya DELETE yapamıyorsunuz. Zaten amacı da bu değil. SQL standardı olarak herhangi bir standart derdi yok. Yani ANSI, ODBC, Microsoft SQL Server uyumluluğu düşünülmemiş. JOIN yapamıyorsunuz (gerek yok), matematiksel operasyonlar ADD, SUBTRACT gibi fonksiyonlar kullanılarak yapılabiliyor . Buna karşılık ek olarak pek çok eklenti fonksiyonu var, bunları uygulamayla gelen Word dosyasından okuyabilirsiniz. GROUP BY, ORDER BY, HAVING ifadeleri kullanılabiliyor. Aggregate (Sum, Count, Avg) fonksiyonları kullanabiliyorsunuz. FROM ifadesi biraz değişik çalışıyor, Burada dosya adı verebiliyorsunuz (Örn: ex040412.log), dosya adlarında maskeleme kullanabilirsiniz. Yani (ex*.log) yazdığınızda o dizindeki bütün "ex" ile başlayan, tipi "log" olan dosyalar incelenebilir. "<n>" ifadesi IISin "n"inci applikasyonunun o anki aktif loglarını inceler. Dosya adlarında boşluk kullanmanız gerekirse, boşluk yerine \u0020 yazın. Bu UNICODEda boşluk demektir. Örnek vermek gerekirse "C:\Program Files\a.log" yerine "C:\Program\u0020Files\xxx.log", C#ta ise şöyle yazılmalı @"C:\Program\u0020Files\a.log" veya "C:\\Program\\u0020Files\\a.log".
Uygulamanın okuyabildiği formatlar;
Ayrıca SELECT ifadesinde FROM ifadesinden sonra TO komutu da eklenmiştir. Bu komutla çıktının nereye yapılacağı belirlenir:
Uygulamayla beraber, detaylı bir Word dokümanı ve hem Scriptler için, hem de SQL ifadelerini açıklayan pek çok örnek dosya geliyor. Mesela IIS saldırılarını listeleyen script kodu var.
Kullanırken her makinaya tüm uygulamayı koymanıza gerek yok. Bir web farmda çalışıyorsanız sadece exe versiyonu kurabilir veya sadece dll versiyonu register edebilirsiniz. İki uygulama birbirinden bağımsız çalışmaktadır.
Sonuç:
Eğer Log dosyalarıyla uğraşmanız gerekiyorsa, bunu LogParser ile yapmanızı tavsiye ederim. Size alışık olduğunuz SQL ortamını veriyor ve elle pek çok kodlama yapma zahmetinden kurtarıyor. Ayrıca performansı kolay kolay geçilemiyor. Eğer ben daha hızlısını yaparım diyorsanız, o size ve vaktinize kalmış.
Mert Sakarya Uygulama Mimarı Doğan Online