Simple Log Service'de JSON biçimli günlüklerin sorgulanması ve analiz edilmesiyle ilgili sık sorulan sorular ve çözümler; dizin yapılandırması, JSON işlevleri ve JSON dizi işleme konularını kapsar.
Örnek günlük
Bu konudaki örneklerde bir sipariş işleme sisteminden alınan JSON günlükleri kullanılır.
{
"request":{
"clientIp":"20xxx30",
"http.path":"/order/buy",
"param":{
"userId": "186453",
"orders":[
{
"commodity":["bread","milk","meat"],
"payment":132
},
{
"commodity":["milk","beer"],
"payment":49
}
]
}
},
"response":"{\"errcode\":400,\"msg\":\"insufficient\"}"
}
requestalanı, JSON biçiminde sipariş isteği bilgilerini içerir. Bir istek, her biri satın alınan ürünleri ve toplam ödeme tutarını içeren birden fazla kullanıcı siparişi barındırabilir.-
responsealanı, sipariş işleme sonucunu içerir.Başarı durumunda
responsealanının değeriSUCCESSolur.Hata durumunda
responsealanının değerierrcodevemsganahtarlarını içeren bir JSON nesnesidir.
Sorgulama ve analiz amacıyla günlükleri Simple Log Service'e aktarmak için Logtail kullanarak Günlükleri JSON modunda toplayın.
Dizin nasıl yapılandırılır
Günlük verilerini sorgulamadan veya analiz etmeden önce bir dizin yapılandırın. JSON günlükleri için dizin yapılandırırken aşağıdaki hususları göz önünde bulundurun.
How to select an index type
Simple Log Service, tam metin dizinlerini ve alan dizinlerini destekler. Kullanım senaryonıza göre seçim yapın. Dizin oluşturun.
Tüm alanları sorgulamak istiyorsanız tam metin dizini oluşturun. Yalnızca belirli alanları sorgulamak istiyorsanız maliyetleri azaltmak için bu alanlar için alan dizinleri oluşturun.
Bir alanda SQL analizi çalıştırmak istiyorsanız bu alan için bir alan dizini oluşturun ve istatistikleri etkinleştirin.
Hem tam metin dizini hem de alan dizinleri yapılandırıldığında, alan dizinine sahip olan alanlar için alan dizini öncelik kazanır.
Örneğin, request ve response alanlarını analiz etmek için bu alanlar için alan dizinleri oluşturun ve istatistikleri etkinleştirin.
How to select a data type for a field in the index configuration
Dizin yapılandırırken bir alanın veri türünü text, long, double veya JSON olarak ayarlayın. Veri türleri.
Bir JSON alanı için veri türü belirlerken aşağıdaki noktaları dikkate alın.
-
Bir alan değeri standart JSON biçiminde değil ancak JSON içeriği barındırıyorsa veri türünü text olarak ayarlayın. Değer standart JSON biçimindeyse JSON olarak ayarlayın.
NotTamamen geçerli olmayan JSON günlükleri için Simple Log Service, geçerli kısımları ayrıştırabilir.
Veri türünü JSON olarak ayarladıktan sonra, daha hızlı sorgular için JSON nesnesi içindeki bir yaprak düğüm için dizin oluşturun. Bu işlem ek dizinleme ücretlerine yol açar.
Simple Log Service, JSON nesnelerindeki yaprak düğümler için dizinlemeyi destekler ancak yaprak düğümler içeren alt düğümler için desteklemez.
Simple Log Service, değerleri JSON dizisi olan alanlar veya bir JSON dizisi içindeki alanlar için dizinlemeyi desteklemez. Bu tür alanlar için bunun yerine gerçek zamanlı analiz amacıyla JSON işlevlerini kullanın.
Örnek günlüğe dayanarak aşağıdaki dizinleri oluşturun.
-
requestalanırequest: Değer JSON biçimindedir. Veri türünü JSON olarak ayarlayın ve istatistikleri etkinleştirin.request.clientIp: Sıkça analiz edilir. Ayrı bir dizin oluşturun, veri türünü text olarak ayarlayın ve istatistikleri etkinleştirin.request.http.path: Nadiren analiz edilir. Ayrı dizin oluşturmayın; bunun yerine JSON işlevlerini kullanarak ihtiyaç duyulduğunda ayrıştırın.request.param: Yaprak düğümler içeren bir alt düğümdür. Dizinleme desteklenmez.request.param.userId: Sıkça analiz edilir. Ayrı bir dizin oluşturun, veri türünü text olarak ayarlayın ve istatistikleri etkinleştirin.request.param.orders: Değer bir JSON dizisidir. Dizinleme desteklenmez.
-
responsealanıresponsealanının değeri her zaman JSON biçiminde değildir. Veri türünü text olarak ayarlayın ve istatistikleri etkinleştirin.
Dizini oluşturduktan sonra, yeni toplanan günlükler dizin yapılandırmasına göre görüntülenir.
How to set an alias
Uzun JSON yaprak düğümü yolları için takma ad ayarlayın. Sütun takma adları.
Dizin yapılandırmasında, JSON türündeki alanların yaprak düğümleri için takma adlar belirtebilirsiniz. Örneğin, request.clientIp için takma adı ip olarak ve request.param.userId için takma adı id olarak ayarlayın.
Alan adları ve takma adlar, bir dizin yapılandırmasındaki tüm alanlar arasında benzersiz olmalıdır.
JSON türündeki alanlar için benzersizlik, yaprak düğümün tam yolu tarafından belirlenir. Örneğin,
responsealanının takma adınıclientIpolarak ayarlamak,request.clientIpalan adı ile çakışmaz.
Dizine alınmış bir JSON alanı nasıl sorgulanır ve analiz edilir
Bir sorgu ve analiz ifadesi sorgu ifadesi|analiz ifadesi biçimini izler. Bir analiz ifadesinde alan adlarını çift tırnak ("") içine, dizeleri ise tek tırnak ('') içine alın. İç içe geçmiş alanlar için tam yolu belirtin; örneğin Key1.Key2.Key3, request.clientIp veya request.param.userId. JSON günlüklerini sorgulayın ve analiz edin.
Örneğin, 186499 numaralı kullanıcı için istemci IP adreslerini bulmak için:
*
and request.param.userId: 186499 |
SELECT
distinct("request.clientIp")
JSON işlevleri ne zaman kullanılır
Sorgu performansı önemli olduğunda, büyük veri kümeleri ve karmaşık ancak sabit JSON yapıları için JSON yaprak düğümlerine yönelik alan dizinleri oluşturun. Daha küçük veri kümeleri veya geçici analizler için maliyet tasarrufu sağlamak amacıyla alan dizinleri olmadan JSON işlevlerini kullanın. JSON işlevleri, JSON içeriğinin dinamik olarak işlenmesini ve analiz edilmesini sağlar. Bazı durumlarda tek seçenek bunlardır.
-
Alan değeri her zaman JSON biçiminde değildir veya ön işlem gerektirir.
Örneğin,
responsealanı yalnızca bir istek başarısız olduğundaerrcodealanını içeren JSON verisi barındırır.errcodedağılımını analiz etmek için başarısız istekleri filtreleyin veerrcodedeğerini bir JSON işleviyle çıkarın.* not response :SUCCESS | SELECT json_extract_scalar(response, '$.errcode') AS errcode
Alan dizine alınamaz. Dizinlemeyi desteklemeyen JSON düğümleri — örneğin
request.paramverequest.param.orders— için gerçek zamanlı analiz çalıştırmanın tek yolu JSON işlevlerini kullanmaktır.
json_extract ve json_extract_scalar arasında nasıl seçim yapılır
Hem json_extract hem de json_extract_scalar JSON nesnelerinden veya dizilerinden içerik çıkarır. Temel fark dönüş türüdür.
-
json_extractbir JSON türü döndürür;json_extract_scalarise varchar türü döndürür.NotBurada söz konusu olan, SLS dizin veri türlerinden farklı olan SQL veri türleridir (varchar, bigint, boolean, JSON, array, date). Bir SQL nesnesinin veri türünü kontrol etmek için
typeofişlevini kullanın. typeof işlevi. json_extractbir JSON nesnesinin herhangi bir alt yapısını ayrıştırabilir.json_extract_scalarise yalnızca skaler yaprak düğümleri (dize, Boolean veya sayı) ayrıştırır ve karşılık gelen dizeyi döndürür.
Her iki işlev de request alanından clientIp alanını çıkarabilir.
-
json_extractkullanımı:* | SELECT json_extract(request, '$.clientIp')Sorgu ve analiz sonuçlarında, takma ad ayarlanmadığından sütun adı varsayılan
_col0olarak görüntülenir ve bu sütunjson_extracttarafından çıkarılanclientIpdeğerini içerir. -
json_extract_scalarkullanımı:* | SELECT json_extract_scalar(request, '$.clientIp')Yukarıdaki sorgu ifadesini çalıştırdıktan sonra, sorgu sonucu çıkarılan alan değerini tek bir
_col0sütununda gösterir.
clientIp değerinin ilk oktettini çıkarmak için önce json_extract_scalar kullanarak clientIp değerini çıkarın, ardından ilk sayıyı elde etmek için split_part işlevini kullanın. split_part işlevi varchar girişi gerektirdiğinden burada json_extract işlevi çalışmaz.
* |
SELECT
split_part(
json_extract_scalar(request, '$.clientIp'),
'.',
1
) AS segment

Çoğu durumda json_extract_scalar işlevini kullanın; varchar dönüş türü diğer SQL işlevleriyle doğal bir şekilde birleşir. JSON yapısıyla doğrudan çalışmanız gerektiğinde json_extract işlevini kullanın. Örneğin, bir istekteki sipariş sayısını (request.param.orders dizisinin uzunluğunu) saymak için:
* |
SELECT
json_array_length((json_extract(request, '$.param.orders')))
Sorgu ve analiz sonuçlarında, _col0 sütunu her bir istekteki JSON dizisinin uzunluğunu (yani sipariş sayısını) döndürür; örnek değerler 2 şeklindedir.
json_extract_scalar varchar türü döndürür. Örneğin, önceki sonuçtaki 2 sayısı varchar türündedir. Toplama gibi hesaplamalar yapmak için önce cast işlevini kullanarak bu değeri bigint türüne dönüştürün. Tür dönüştürme işlevleri.
JSON yolu nasıl ayarlanır
json_extract gibi işlevleri kullanırken, çıkarılacak JSON nesnesinin hedef kısmını belirtmek için bir JSON yolu tanımlayın. Biçim $.a.b şeklindedir; burada $ kök düğümü temsil eder ve noktalar (.) alt düğümlere referans verir.
http.path, http path veya http-path gibi özel karakterler içeren JSON alan adları için nokta yerine köşeli parantezler [] kullanın ve alan adını çift tırnak içine alın. Örnek: * |SELECT json_extract_scalar(request, '$["http.path"]').
Bir SDK üzerinden sorgulama yaparken çift tırnak işaretlerini kaçış karakterleriyle belirtin. Örnek: * | select json_extract_scalar(request, '$[\"http.path\"]').
Bir JSON dizisinden bir öğe çıkarmak için sıfır tabanlı indeks ile köşeli parantezler [] kullanın.
-
Kullanıcının ilk siparişindeki ödeme tutarını görüntüleyin:
* | SELECT json_extract_scalar(request, '$.param.orders[0].payment')Sorgu sonucu tablosunda,
_col0sütununda iki satır gösterilir ve her ikisinin değeri de132şeklindedir. -
Kullanıcının ilk siparişinde satın alınan ikinci ürünü görüntüleyin:
* | SELECT json_extract_scalar(request, '$.param.orders[0].commodity[1]')_col0sütunu, her ikisinin değeri demilkolan iki kayıt döndürür.
JSON dizisi nasıl analiz edilir
Bir JSON dizisini analiz etmek için diziyi genişletmek üzere cast işlevini UNNEST yan tümcesiyle birleştirin, ardından sonuçları toplayın.
Example 1
Tüm başarılı siparişler için toplam ödeme tutarını hesaplamak için:
-
Başarılı istekleri filtreleyin ve
json_extractkullanarakordersalanını çıkarın.* and response: SUCCESS | SELECT json_extract(request, '$.param.orders')_col0 [{"commodity":["bread","milk","meat"],"payment":132},{"commodity":["milk","beer","rice"],"payment":49}] [{"commodity":["bread","milk","meat"],"payment":132},{"commodity":["milk","beer","rice"],"payment":49}] -
JSON dizisini bir dizi türüne dönüştürün.
* and response: SUCCESS | SELECT cast( json_extract(request, '$.param.orders') AS array(json) )_col0 ["{"commodity":["bread","milk","meat"],"payment":132}","{"commodity":["milk","beer","rice"],"payment":49}"] ["{"commodity":["bread","milk","meat"],"payment":132}","{"commodity":["milk","beer","rice"],"payment":49}"] -
Diziyi tek tek satırlara genişletmek için
UNNESTkullanın.* and response: SUCCESS | SELECT orderinfo FROM log, unnest( cast( json_extract(request, '$.param.orders') AS array(json) ) ) AS t(orderinfo)Sorgu ve analiz sonuçları:
orderinfo {"commodity":["milk","beer","rice"],"payment":49} {"commodity":["milk","beer","rice"],"payment":49} -
json_extract_scalarkullanarakpaymentdeğerini çıkarın, bigint türüne dönüştürün ve toplamını alın.* and response: SUCCESS | SELECT sum( cast( json_extract_scalar(orderinfo, '$.payment') AS bigint ) ) FROM log, unnest( cast( json_extract(request, '$.param.orders') AS array(json) ) ) AS t(orderinfo)Dönüş sonucu
10860şeklindedir.
Example 2
Tüm başarılı isteklerdeki her bir ürünün miktarını saymak için: orders alanını çıkarın, array(json) türüne dönüştürün ve UNNEST ile genişletin; her satır bir siparişi temsil eder. commodity alanını çıkarın, tekrar dönüştürün ve genişletin; her satır bir ürünü temsil eder. Gruplayın ve sayın.
*
and response: SUCCESS |
SELECT
item,
count(1) AS cnt
FROM (
SELECT
orderinfo
FROM log,
unnest(
cast(
json_extract(request, '$.param.orders') AS array(json)
)
) AS t(orderinfo)
),
unnest(
cast(
json_extract(orderinfo, '$.commodity') AS array(json)
)
) AS t(item)
GROUP BY
item
ORDER BY
cnt DESC
Sorgu sonuçları item ve cnt olmak üzere iki sütun içerir. Her bir ürün için satın alma sayısı istatistikleri şöyledir:
"milk": 120
"bread": 60
"rice": 60
"beer": 60
"meat": 60