Yapılandırılmış Günlüğe kaydetmenin ve temel günlüğe kaydetmenin yararları


110

Yeni bir uygulama oluşturuyoruz ve yapılandırılmış günlük kaydı eklemek istiyorum. İdeal kurulumum SerilogC # kodumuz ve BunyanJS'miz gibi olacak. Bunlar beslenecek fluentdve daha sonra herhangi bir şeye çıkabilecektir, başlangıçta düşünüyordum elasticsearch + kibana. Zaten bir MySQL veritabanımız var, bu yüzden kısa vadede Serilog + Bunyan kurulumunu ve geliştiricilerini kullanmakla daha fazla ilgileniyorum ve akıcı ve gerisini biraz daha fazla zaman harcayarak MySQL'e giriş yapabiliriz.

Bununla birlikte, daha deneyimli kodlayıcılarımızdan biri sadece şöyle bir şeyi yapmayı tercih eder: MySQL'e karşı select deyimlerini log.debug("Disk quota {0} exceeded by user {1}", quota, user);kullanarak log4netve sonra çalıştır:SELECT text FROM logs WHERE text LIKE "Disk quota";

Olduğu söyleniyor, hangi yaklaşım daha iyi ve / veya kayıt sistemi türünü seçerken nelere dikkat etmeliyiz?


Yapılan düzenlemelere katılıyorum. Yapısal ve temel günlüklemenin yararlarını ve farkını anlamaya çalıştığım için birine bir şey kanıtlamaya çalışmıyorum. Yapılandırılmış zihnimde bize özellikle kütük kaynaklarında ve daha sonra verilerini nasıl gösterebileceğimiz konusunda daha fazla esneklik veriyor. Anladığım kadarıyla, neden temel günlüklemenin ve MySQL'de arama yapmanın yapısal günlüklemeden daha iyi / daha kötü olduğunu açıklayamıyorum.
DTI-Matt

2
@ DTI-Matt serilog'un yapılandırılmış günlüğü yalnızca temel günlüğe kaydetmedir, yalnızca yazdırdığınız nesneleri biçimlendirir - ToString'i çok kolay sürerek kendiniz yapabileceğiniz bir şey. Daha önemli bir husus, günlük dosyalarının yapılandırılması ve yönetilmesidir, bir dize diğerine biçimlendirilmesinin bir yolu değil, diğeri performanstır. Eğer dev log4net kullanmak istiyorsa (ki bu iyi bir günlükleme kütüphanesidir), o zaman tercih ettiğiniz serilog (havalı görünen) tercihlerinden biri de "problem arayışı içinde olan" şeylerden biridir.
gbjbaanb

@ DTI-Matt Serilog'a bakıldığında log4net'e çok benziyor. log4net, config üzerinde yapılandırılmış loglar yaratır. Yapılandırılmış ve bir tabloya yazılan ek bilgilere sahip olabileceğiniz için günlük mesajlarını aramanıza gerek yoktur. Ayrıca fluentd için Log4net yapılandırmak tipstuff.org/2014/05/...
RubberChickenLeader

Buradaki kavramsal sorular fikrini anlamayan bazı aptallar olduğuna dikkat edin. ETL kabiliyetlerini ele almak için veritabanı uygulamalarının yönünü sormak v. kodu size bazı ciddi indirimler sağlayacaktır. Sorunun da doğrama blokunda olacağını varsayıyorum.
user3916597 9:16

2
@gbjbaanb Serilog, olayları metin olarak oluştururken log4net ile aynı şekilde çalışır, ancak günlükleri depolamak için yapılandırılmış bir format kullanırsanız, adlandırılmış özellikleri iletilen argümanlarla ilişkilendirir (ör. regex olmadan arama / filtrelemeyi desteklemek vb.) ) HTH!
Nicholas Blumhardt

Yanıtlar:


140

Yapılandırılmış yaklaşımla, metin girişleri kullanılarak (bazen aşırı düzeyde) ek çaba gösterilmeksizin taklit edilemeyen iki temel gelişme vardır .

Etkinlik Türleri

Log4net ile iki olay yazdığınızda :

log.Debug("Disk quota {0} exceeded by user {1}", 100, "DTI-Matt");
log.Debug("Disk quota {0} exceeded by user {1}", 150, "nblumhardt");

Bunlar benzer metinler üretecek:

Disk quota 100 exceeded by user DTI-Matt
Disk quota 150 exceeded by user nblumhardt

Ancak, makine işleme söz konusu olduğunda, bunlar sadece iki satır farklı metindir.

Tüm "disk kotası aşıldı" olaylarını bulmak isteyebilirsiniz, ancak olayları aramanın basit olayı, like 'Disk quota%'başka bir olay olduğu gibi gerçekleşir görünmez düşecektir:

Disk quota 100 set for user DTI-Matt

Metin kaydı, başlangıçta etkinliğin kaynağı hakkında sahip olduğumuz bilgileri atar ve bu genellikle günlükleri daha fazla ve daha ayrıntılı eşleştirme ifadeleriyle okurken yeniden oluşturulmalıdır.

Buna karşılık, aşağıdaki iki Serilog olayını yazdığınızda :

log.Debug("Disk quota {Quota} exceeded by user {Username}", 100, "DTI-Matt");
log.Debug("Disk quota {Quota} exceeded by user {Username}", 150, "nblumhardt");

Bunlar log4net sürümüne benzer metin çıktısı üretir, ancak sahne arkasında "Disk quota {Quota} exceeded by user {Username}" mesaj şablonu her iki olay tarafından da taşınır.

Uygun bir havuz ile sorguları daha sonra yazabilir where MessageTemplate = 'Disk quota {Quota} exceeded by user {Username}'ve disk kotasının aşıldığı olayları tam olarak alabilirsiniz .

Tüm mesaj şablonunu her log olayı ile birlikte saklamak her zaman uygun değildir, bu nedenle bazı mesajlar mesaj şablonunu sayısal bir EventTypedeğere sahiptir (örneğin 0x1234abcd), ya da bunu kendiniz yapmak için günlük boru hattına bir zenginleştirici ekleyebilirsiniz .

Aşağıdaki bir sonraki farktan daha ince, ancak büyük kütük hacimleriyle uğraşırken çok güçlü bir fark.

Yapılandırılmış Veriler

Yine disk alanı kullanımıyla ilgili iki olayı göz önüne alarak, belirli bir kullanıcıyı sorgulamak için metin kayıtlarını kullanmak yeterince kolay olabilir like 'Disk quota' and like 'DTI-Matt'.

Ancak, üretim teşhisi her zaman kolay değildir. Disk kotasının aşıldığı olayların 125 MB'ın altında olduğunu bulmak için gerekli olduğunu hayal edin?

Serilog ile bu, bir çeşidi kullanan çoğu lavaboda mümkündür:

Quota < 125

Düzenli ifadeden sorgunun bu tür Oluşturma olan olası, ancak yorucu hızlı olur ve genellikle son çare olarak biter.

Şimdi buna bir etkinlik türü ekleyin:

Quota < 125 and EventType = 0x1234abcd

Burada üretimin hata ayıklamasını birinci sınıf geliştirme faaliyeti gibi hissettirmek için bu özelliklerin basit bir şekilde nasıl birleştiğini görmeye başlarsınız.

Bir başka avantaj, belki de öne geçmek için kolay değildir, ancak üretim hata ayıklaması regex korsanlığı ülkesinden kaldırıldıktan sonra, geliştiriciler günlükleri çok daha fazla değerlendiriyor ve yazarken daha fazla özen ve dikkat göstermeye başlıyor. Daha iyi günlükler -> daha kaliteli uygulamalar -> her yerde daha fazla mutluluk.


4
Bu cevabı seviyorum. çok iyi yazılmış ve nedense açıklayamam, beni koltuğumun kenarında tutuyor.
jokab

16

İşlem yapmak için günlükleri toplarken, bazı veritabanlarına ayrıştırmak ve / veya işlenmiş günlükleri daha sonra aramak için yapılandırılmış günlük kullanmak , işlemlerin bir kısmını daha kolay / verimli hale getirir. Ayrıştırıcı bilinen yapıdan ( örneğin, JSON, XML, ASN.1, ne olursa olsun) faydalanabilir ve düzenli ifadelerin aksine (derleme ve yürütme için hesaplama açısından pahalı olan (göreceli olarak)) durum makineleri kullanılır. İş arkadaşınız tarafından önerilenler gibi serbest biçimli metnin ayrıştırılması, düzenli ifadelere ve değişmeyen bu metne güvenme eğilimindedir . Bu, serbest biçimli metni ayrıştırma yerine kırılgan hale getirebilir ( örneğin ayrıştırma, koddaki tam metne sıkıca bağlıdır).

Ayrıca, arama / arama durumunu da göz önünde bulundurun, örneğin :

SELECT text FROM logs WHERE text LIKE "Disk quota";

LIKEKoşullar, her textsatır değeriyle karşılaştırma yapılmasını gerektirir ; Yine, bu özellikle hesaplamalı olarak pahalıdır, özellikle joker karakterler kullanıldığında:

SELECT text FROM logs WHERE text LIKE "Disk %";

Yapılandırılmış günlük kaydıyla, disk hatasıyla ilişkili günlük iletiniz JSON'de şöyle görünebilir:

{ "level": "DEBUG", "user": "username", "error_type": "disk", "text": "Disk quota ... exceeded by user ..." }

Bu tür bir yapının alanları örneğin SQL tablo sütun adlarıyla kolayca eşlenebilir; bu, aramanın daha belirgin / ayrıntılı olabileceği anlamına gelir:

SELECT user, text FROM logs WHERE error_type = "disk";

Dizini, bu sütun değerleri için yan tümceleri kullanmadığınız süreceLIKE , sık sık aramayı / aramayı beklediğiniz sütunlara yerleştirebilirsiniz . Günlük mesajınızı belirli kategorilere ayırdıkça, daha fazla hedeflenmiş arama yapabilirsiniz. Örneğin, error_typeyukarıdaki örnekteki alana / sütuna ek olarak, hatta "error_category": "disk", "error_type": "quota"veya bir şeyler bile yapabilirsiniz.

Eğer günlük mesajlarında Ne kadar çok yapı (örneğin daha fazla ayrıştırma / arama sistemleri fluentd, elasticsearch, kibana) o yapının yararlanmak ve daha fazla hız ve daha az CPU / bellek ile görevlerini gerçekleştirebilir.

Bu yardımcı olur umarım!


1
+1 Bunun sadece hız ve verimlilik ile ilgili olmadığını da eklemek istiyorum. Yapılandırılmış günlük kaydı ve dolayısıyla "yapılandırılmış sorgular" kullanılırken arama sonuçlarının alaka düzeyi daha yüksek olacaktır. Bu olmadan, farklı bağlamlarda ortaya çıkan kelimeleri aramak size tonlarca alakasız sonuç verecektir.
Marjan Venema

1
Benden de +1, sanırım bu çiviler. Olay türleri konusunda da genişlemek için aşağıya biraz farklı bir formülasyon eklendi.
Nicholas Blumhardt

8

Uygulamanız günde birkaç yüz günlük mesajı oluşturduğunda, yapılandırılmış günlükten çok fazla fayda elde edemezsiniz. Kesinlikle birçok konuşlandırılmış uygulamadan gelen saniyede birkaç günlük mesajınız olduğunda bunu yapacaksınız.

İlgili olarak, günlük mesajlarının ELK Yığınına sona erdiği kurulum , SQL'de oturum açmanın bir darboğaz haline geldiği ölçek için de uygundur.

SQL ile "basit loglama ve arama" kurulumunu gördüm select .. likeve regexps parçalara ayrıldığı sınırlara kadar zorlandı - yanlış pozitifler, eksiklikler, knwon hataları olan korkunç bir filtre kodu var ve hiç kimse dokunmak istemiyor, Filtrenin varsayımlarına uymayan yeni günlük mesajları, raporları kırmak için kodlardaki günlük ifadelerine dokunma isteksizlikleri vb.

Bu yüzden bu problemi daha iyi ele almak için birkaç yazılım paketi ortaya çıkıyor. Orada Serilog, bunu duymak olduğunu NLog ekibi bu konuyla ilgileniyor ve biz yazdığı StructuredLogging.Jsonnlog için ben de yeni görüyoruz, ASP.Net çekirdek günlüğü soyutlamalar "mümkün günlüğü sağlayıcıları uygulamak ... yapılandırılmış günlüğü için yapmak".

StructuredLogging ile bir örnek. Böyle bir NLog günlüğüne giriş yaparsınız:

logger.ExtendedError("Order send failed", new { OrderId = 1234, RestaurantId = 4567 } );

Bu yapılandırılmış veri, kibana'ya gider. Değer 1234, OrderIdgünlük girişi alanında saklanır . Daha sonra, örneğin tüm günlük girişleri için kibana sorgu sözdizimini kullanarak arama yapabilirsiniz @LogType:nlog AND Level:Error AND OrderId:1234.

Messageve OrderIdşimdi sadece tam veya tam olmayan eşleşmeler için aranabilecek veya sayılar için toplanabilecek alanlardır. Bu güçlü ve esnektir.

Gönderen StructuredLogging iyi uygulamalar :

Kaydedilen mesaj her seferinde aynı olmalıdır. Sabit bir dize olmalı, kimlikleri veya miktarları gibi veri değerlerini içerecek şekilde biçimlendirilmiş bir dize değil. O zaman aramak kolaydır.

Kaydedilen mesaj farklı olmalıdır, yani ilgisiz bir log ifadesi tarafından üretilen mesajla aynı olmamalıdır. Öyleyse onu aramak ilgisiz şeylerle eşleşmiyor.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.