Azure'da Trace.WriteLine yapacak olsak?

0 dakikada yazıldı

22112 defa okundu

Düzenle

Development süreçlerinizde her ne kadar Azure SDK ile beraber gelen emülatörü kullanacak olsanız da maalesef bazıt testleri doğrudan Azure üzerinde yapmak zorunda da kalabiliyoruz. Bu çok da anormal bir durum değil :) Sonuç itibari ile Azure üzerinde bir "Staging" ortamı tutmak için gerekli altyapı Azure'da var. Tabi aslına bakarsanız Staging dışında bir de Development ortamı tutmak gerekiyor ama şimdilik çok da oraları karıştırmayalım :) Peki nedir çözüm aradığımız sorun? Basit bir "code instrumentation" çözümü arıyoruz ve bunun da azure'daki development ortamımızda çalışmasını istiyoruz. Eminim ki çoğunuzun aklına "Trace"'ler gelecektir. En basit şekli ile development süreçlerinde kullandığımız ve epey de işimize yarayan şeylerden biri Trace'ler Azure ortamına geçince ilginç bir problem olabiliyor.

Diyelim ki attık uygulamayı Azure ortamına, scaling'i de hallettik vs... Trace verisini nereden, nasıl toplayacaksınız? Uygulama birden çok sunucuda çalışıyor unutmayın. Bu sunucuların her an "ReImage" olabileceğini ve aslında state'lerinin saklanmadığını da düşünürsek bizim Trace bilgilerini kalıcı olarak ve ortak bir yerde saklayabiliyor olmamız gerek. Aklınıza birşey geldi mi? Azure'da kalıcı veri saklamak için ne kullanıyorduk? Storage Servisleri :)

Trace Verilerini doğrudan Table Services'a alsak?

Bu fikri ilk duyduğunuzda hemen aklınıza "ya maliyeti?" sorusu gelebilir :) Her Trace'de bir REST call ile veriyi merkezi bir yere atmak hem performans açısından hem de maddi açıdan sıkıntı yaratabilir ama unutmayın bunu Production için düşünmüyoruz aslında. Development süreçlerimizde kullanmak için düşünüyoruz. Aslına bakarsanız Prod için de kullanabilirsiniz :) ama en azından bu makalede bakacağımız kısmın üzerine bir "instance seviyesinde" cache tutup önce Trace'leri oraya dumb etseniz ve periyodik aralıklarla Table Services'a atsanız daha iyi olur. Nitekim bu işi yapan Azure Diagnostics servisleri de var aslında ama tüm bunlara bulaştığınızda zaten yavaş yavaş Production kalitesinde bir çözüme doğru ilerlemiş oluyorsunuz. Bizim istediğimiz ise basit, anlık, herhangi bir gecikme olmadan Development ortamımızda Trace'leri görmek! O kadar! :)

O zaman başlayalım... Önce Table Services'a erişimimizi düzenleyelim.

Table Services konusunu daha önce detayları ile toplam üç yazıda işlemiştik. Yazılaraburadan ulaşabilirsiniz. Çok detaylarına girmeden hızlıca Trace nesnemizi bir yaratalım.

[C#]

public class TraceObject : TableServiceEntity\ {\     public string Message { getset; }\ }

Trace nesnemiz görüldüğü gibi epey basit :) Sadece Trace'de verilen tek bir metni kaydedeceğiz. Siz isterseniz ileriki adımları da biraz daha özelleştirecek ek verilerin kaydedilmesini de sağlayabilirsiniz.

[C#]

public class TraceContext : TableServiceContext\ {\     private static CloudStorageAccount storageAccount =\       CloudStorageAccount.FromConfigurationSetting(Setup.ConfigurationSettingKey);\ \     public TraceContext()\         : base(storageAccount.TableEndpoint.AbsoluteUri,\             storageAccount.Credentials)\     {\     }\ \     public DataServiceQuery\<TraceObject> Traces\     {\         get\         {\             return CreateQuery\<TraceObject>("Traces");\         }\     }\ }

Yukarıda Table Services'dan kullanacağımız "Traces" adındaki tabloya erişim için gerekli TableContext'imizi yaratmış durumdayız. Böylece artık işin Table Services tarafı tamamlandı gibi. Tabi söz konusu Traces tablosunu yaratmayı da unutmayın :)

Bir sonraki adımda sıra geliyor özel bir Trace Listener yaratmaya.

[C#]

public class CustomTraceListener : System.Diagnostics.TraceListener\ {\     public override void Write(string message)\     {\         WriteLine(message);\     }\ \     public override void WriteLine(string message)\     {\         var traceContext = new TraceContext();\         var newTrace = new TraceObject\         {\             PartitionKey = DateTime.Now.Year.ToString(),\             RowKey = DateTime.Now.ToOADate().ToString(),\             Message = message\         };\         traceContext.AddObject("Traces", newTrace);\         traceContext.SaveChanges();\     }\ }

Yarattığımız bu CustomTraceListener'ın içinde Write veWriteLine metodlarını implemente etmemiz gerek. Siz tercihinizi göre tabi ki farklı hareketler de yapabilirsiniz :) Bu örnekte WriteLine içerisinde yeni bir TraceObject yaratarak Table Services'daki tablomuza Insert işlemini gerçekleştiriyoruz. Böylece herTrace.WriteLine çağrıldığında mesaj doğrudan Table Services'a aktarılacak.

[C#]

CustomTraceListener TListener = new CustomTraceListener();\ Trace.Listeners.Add(TListener);

Son olarak yapmanız gereken uygulamanız başladığında bizim CustomTraceListener'dan bir tane yaratıp uygulamanın Listener listesine eklemek. Bunun ister WorkerRole'ün OnStart'ında ister web sitenizin App_Start'ında yapabilirsiniz. Artık tüm Trace'ler doğrudan Table Services'a gidecek.

Unutmadan, diğer detayları daha önceki yazılarda inceledik diye bahsetmedim ama :) StorageClient için ConfigurationPublisher'ı set etmeyi unutmayın. Yukarıdaki kodlarda "Setup.ConfigurationSettingKey" diye geçen kısıma da Storage Account connection string'ini vermeniz gerekecek.Table Services ve Storage Account konusunda blogda birçok yazı var. Göz atmanızda fayda var.

Kolay gelsin.