Requêtes SQL prêtes à l'emploi pour les scénarios d'analyse de journaux courants : alertes, surveillance du trafic, analyse de la latence et observabilité des services web Tomcat.
Déclencher une alerte lorsque le taux d'erreur dépasse 40 % au cours des 5 dernières minutes
Pour alerter en cas de pic d'erreurs HTTP 500, calculez le taux d'erreur par sujet sur des fenêtres de 5 minutes. Utilisez la fonction max_by afin d'identifier la fenêtre présentant le nombre d'erreurs le plus élevé, puis filtrez les sujets pour lesquels cette fenêtre représente plus de 40 % du total des erreurs. La clause HAVING applique les deux conditions suivantes : un taux d'erreur supérieur à 40 % et un minimum de 500 erreurs totales, ce qui permet d'exclure les faux positifs sur les sujets à faible trafic.
status:500 | select __topic__, max_by(error_count,window_time)/1.0/sum(error_count) as error_ratio, sum(error_count) as total_error from (
select __topic__, count(*) as error_count , __time__ - __time__ % 300 as window_time from log group by __topic__, window_time
)
group by __topic__ having max_by(error_count,window_time)/1.0/sum(error_count) > 0.4 and sum(error_count) > 500 order by total_error desc limit 100
Collecter des statistiques de trafic et configurer des alertes
Pour surveiller le trafic entrant par minute et déclencher une alerte lorsqu'il descend sous un seuil donné, agrégez le trafic par minute et normalisez-le pour obtenir un débit par minute. Le diviseur greatest(max(__time__) - min(__time__),1) gère les fenêtres inférieures à une minute aux limites de la requête : la fonction greatest garantit que le dénominateur est au moins égal à 1, évitant ainsi toute division par zéro lorsque tous les événements se produisent dans la même seconde.
* | SELECT SUM(inflow) / greatest(max(__time__) - min(__time__),1) as inflow_per_minute, date_trunc('minute',__time__) as minute group by minute
Calculer la latence moyenne par taille de données
Pour comprendre l'impact de la taille des données sur la latence, répartissez les requêtes dans cinq plages de taille à l'aide de l'expression CASE WHEN et calculez la latence moyenne pour chaque groupe. Cette approche révèle si les charges utiles volumineuses sont à l'origine des pics de latence.
* | select avg(latency) as latency , case when originSize < 5000 then 's1' when originSize < 20000 then 's2' when originSize < 500000 then 's3' when originSize < 100000000 then 's4' else 's5' end as os group by os
Renvoyer les pourcentages des différents résultats
Pour visualiser la part de chaque département dans le total, utilisez une sous-requête afin de calculer les comptes par département et une fonction de fenêtrage pour obtenir le total global. L'expression sum(c) over() calcule la somme sur toutes les lignes sans les regrouper, ce qui vous permet de diviser le compte de chaque ligne par le total en une seule passe.
* | select department, c*1.0/ sum(c) over () from(select count(1) as c, department from log group by department)
Compter le nombre d'URL répondant à la condition de requête
Pour compter les requêtes de connexion et d'inscription par minute sans recourir à des branchements complexes, utilisez la fonction COUNT_IF avec un motif LIKE pour chaque type d'URL. La fonction COUNT_IF est plus concise que l'expression équivalente CASE WHEN et plus facile à étendre lorsque vous devez suivre des motifs d'URL supplémentaires.
* | select count_if(uri like '%login') as login_num, count_if(uri like '%register') as register_num, date_format(date_trunc('minute', __time__), '%m-%d %H:%i') as time group by time order by time limit 100
Analyse agrégée générale
Interroger la distribution mondiale des clients par PV
Pour identifier les pays d'origine de vos clients et le volume de trafic généré par chacun, utilisez la fonction ip_to_country afin de résoudre les adresses IP des clients en noms de pays, puis groupez les résultats par pays et comptez les pages vues (PV). Affichez les résultats sur une carte mondiale ; consultez la rubrique Configure a world map pour plus de détails.
* |
select
ip_to_country(client_ip) as ip_country,
count(*) as pv
group by
ip_country
order by
pv desc
limit
500
Interroger la catégorie et la tendance des PV par méthode de requête
Pour suivre l'évolution des différentes méthodes de requête HTTP au fil du temps, tronquez les horodatages à la minute près à l'aide de date_format(date_trunc('minute', ...)), puis groupez les résultats par heure et par request_method afin d'obtenir le nombre de PV par méthode. Affichez les résultats sur un graphique linéaire en définissant l'axe des x sur t, l'axe des y sur pv et la colonne d'agrégation sur request_method. Pour en savoir plus, consultez la rubrique Line chart.
* |
select
date_format(date_trunc('minute', __time__), '%m-%d %H:%i') as t,
request_method,
count(*) as pv
group by
t,
request_method
order by
t asc
limit
10000
Interroger la distribution des requêtes par agent utilisateur et PV
Pour ventiler le trafic par agent utilisateur, y compris le volume de requêtes, la taille du trafic et la distribution des codes d'état, groupez les données par http_user_agent et calculez : le total des PV, le trafic des requêtes et des réponses en Mo (arrondi à deux décimales), ainsi que le pourcentage des réponses pour chaque plage de codes d'état (2xx, 3xx, 4xx, 5xx) à l'aide d'expressions CASE WHEN. Affichez les résultats dans un tableau. Pour plus d'informations, consultez la rubrique Basic table.
* |
select
http_user_agent as "User agent",
count(*) as pv,
round(sum(request_length) / 1024.0 / 1024, 2) as "Request traffic (MB)",
round(sum(body_bytes_sent) / 1024.0 / 1024, 2) as "Response traffic (MB)",
round(
sum(
case
when status >= 200
and status < 300 then 1
else 0
end
) * 100.0 / count(1),
6
) as "Percentage of status code 2xx (%)",
round(
sum(
case
when status >= 300
and status < 400 then 1
else 0
end
) * 100.0 / count(1),
6
) as "Percentage of status code 3xx (%)",
round(
sum(
case
when status >= 400
and status < 500 then 1
else 0
end
) * 100.0 / count(1),
6
) as "Percentage of status code 4xx (%)",
round(
sum(
case
when status >= 500
and status < 600 then 1
else 0
end
) * 100.0 / count(1),
6
) as "Percentage of status code 5xx (%)"
group by
"User agent"
order by
pv desc
limit
100
Interroger la consommation quotidienne et les prévisions de tendance pour le mois en cours
Pour visualiser les dépenses quotidiennes réelles ainsi qu'une prévision pour le reste du mois, dédupliquez les enregistrements de facturation par RecordID, agrégez les totaux quotidiens et transmettez le résultat à la fonction sls_inner_ts_regression. Cette fonction prend l'horodatage, le total quotidien, un tableau d'étiquettes, l'intervalle de prévision en secondes (86400 pour une prévision quotidienne) et le nombre de points de prévision (60), puis renvoie les valeurs réelles et prédites. Lorsque res.real est égal à NaN, la ligne correspond à un point de prévision ; l'expression CASE WHEN n'affiche les valeurs de prévision que pour les dates futures. Affichez les résultats sur un graphique linéaire en définissant l'axe des x sur time et en utilisant deux axes des y pour la consommation réelle et prévue. Pour plus d'informations, consultez la rubrique Line chart.
source :bill |
select
date_format(res.stamp, '%Y-%m-%d') as time,
res.real as "Actual consumption",case
when is_nan(res.real) then res.pred
else null
end as "Forecast consumption",
res.instances
from(
select
sls_inner_ts_regression(
cast(day as bigint),
total,
array ['total'],
86400,
60
) as res
from
(
select
*
from
(
select
*,
max(day) over() as lastday
from
(
select
to_unixtime(date_trunc('day', __time__)) as day,
sum(PretaxAmount) as total
from
(
select
RecordID,
arbitrary(__time__) as __time__,
arbitrary(ProductCode) as ProductCode,
arbitrary(item) as item,
arbitrary(PretaxAmount) as PretaxAmount
from
log
group by
RecordID
)
group by
day
order by
day
)
)
where
day < lastday
)
)
limit
1000
Interroger le pourcentage de consommation de chaque service pour le mois en cours
Pour identifier les services représentant la plus grande part de votre facture, agrégez les dépenses par ProductName, classez les services par dépense totale à l'aide de la fonction de fenêtrage row_number, puis regroupez les services classés au-delà de la 7e place (ou affichant des frais nuls ou négatifs) dans une catégorie « Other ». Affichez les résultats sur un graphique en anneau. Pour plus d'informations, consultez la rubrique Configure a donut chart.
source :bill |
select
case
when rnk > 6
or pretaxamount <= 0 then 'Other'
else ProductName
end as ProductName,
sum(PretaxAmount) as PretaxAmount
from(
select
*,
row_number() over(
order by
pretaxamount desc
) as rnk
from(
select
ProductName,
sum(PretaxAmount) as PretaxAmount
from
log
group by
ProductName
)
)
group by
ProductName
order by
PretaxAmount desc
limit
1000
Comparer les dépenses d'hier avec celles du même jour le mois dernier
Pour comparer les dépenses d'hier avec celles du même jour le mois précédent, utilisez la fonction compare avec un décalage de 604 800 secondes (7 jours). La fonction COALESCE garantit que les jours sans frais renvoient 0 plutôt que NULL. Le tableau de sortie diff contient trois valeurs : diff[1] correspond aux dépenses d'hier, diff[2] aux dépenses du même jour le mois dernier, et diff[3] au ratio. Utilisez la fonction round pour arrondir la valeur de dépense interne à trois décimales, puis formatez les valeurs externes de diff à deux décimales. Multipliez enfin diff[3] par 100 et soustrayez 100 pour exprimer le ratio en pourcentage de variation. Affichez les résultats sur un graphique de tendance ; consultez la rubrique Trend chart pour plus de détails.
source :bill |
select
round(diff [1], 2),
round(diff [2], 2),
round(diff [3] * 100 -100, 2)
from(
select
compare("Expense of the previous day", 604800) as diff
from(
select
round(coalesce(sum(PretaxAmount), 0), 3) as "Expense of the previous day"
from
log
)
)
Analyse des services web Tomcat
Analyser la tendance des états de requête Tomcat
Pour observer l'évolution des codes d'état des requêtes Tomcat au fil du temps, utilisez la fonction date_trunc afin de tronquer les horodatages à la minute près et la fonction date_format pour formater l'heure en heures et minutes. Groupez ensuite les résultats par heure et par status afin de compter les requêtes par code d'état et par minute. Affichez les résultats sur un diagramme de flux en définissant l'axe des x sur time, l'axe des y sur count et la colonne d'agrégation sur status. Pour plus d'informations, consultez la rubrique Flow chart.
* |
select
date_format(date_trunc('minute', __time__), '%H:%i') as time,
COUNT(1) as c,
status
GROUP by
time,
status
ORDER by
time
LIMIT
1000
Interroger la distribution des PV et UV pour l'accès Tomcat au fil du temps
Pour suivre simultanément les pages vues (PV) et les visiteurs uniques (UV) sur la même chronologie, utilisez la fonction time_series afin de regrouper les événements par intervalles de 2 minutes et la fonction approx_distinct pour compter les valeurs uniques de remote_addr. La fonction approx_distinct utilise l'algorithme HyperLogLog pour une déduplication approximative efficace, offrant une précision suffisante pour la surveillance sans le coût associé à une déduplication exacte. Affichez les résultats sur un graphique linéaire multi-axes en définissant l'axe des x sur time et en utilisant deux axes des y pour uv et pv. Pour plus d'informations, consultez la rubrique Add a line chart with multiple y-axes.
* |
select
time_series(__time__, '2m', '%H:%i', '0') as time,
COUNT(1) as pv,
approx_distinct(remote_addr) as uv
GROUP by
time
ORDER by
time
LIMIT
1000
Interroger le nombre de requêtes d'erreur Tomcat et comparer avec l'heure précédente
Pour comparer le nombre actuel d'erreurs avec celui d'il y a une heure, utilisez la fonction compare avec un décalage de 3 600 secondes. La fonction renvoie un tableau : c1 correspond au nombre actuel d'erreurs, c2 au nombre d'erreurs il y a 3 600 secondes, et c3 à la variation en pourcentage (c1/c2 * 100 - 100). Affichez les résultats sur un graphique en anneau en utilisant c1 comme valeur d'affichage et c3 comme valeur de comparaison. Pour plus d'informations, consultez la rubrique Configure a donut chart.
status >= 400 |
SELECT
diff [1] AS c1,
diff [2] AS c2,
round(diff [1] * 100.0 / diff [2] - 100.0, 2) AS c3
FROM
(
select
compare(c, 3600) AS diff
from
(
select
count(1) as c
from
log
)
)
Interroger les 10 URI les plus demandées dans les requêtes Tomcat
Pour identifier les URI les plus sollicitées, groupez les données par request_uri, comptez les PV par URI et renvoyez les 10 premières dans l'ordre décroissant. Affichez les résultats sur une jauge à barres en définissant l'axe des x sur page et l'axe des y sur pv. Pour plus d'informations, consultez la rubrique Bar gauge.
* |
SELECT
request_uri as page,
COUNT(*) as pv
GROUP by
page
ORDER by
pv DESC
LIMIT
10
Interroger les types et la distribution des clients Tomcat
Pour comprendre quels clients accèdent à votre serveur Tomcat, groupez les données par user_agent et comptez les requêtes par type. Affichez les résultats sur un graphique en anneau en définissant le type sur user_agent et la colonne de valeur sur c. Pour plus d'informations, consultez la rubrique Configure a donut chart.
* |
SELECT
user_agent,
COUNT(*) AS c
GROUP BY
user_agent
ORDER BY
c DESC
Collecter des statistiques sur le trafic sortant Tomcat
Pour surveiller le trafic sortant Tomcat au fil du temps, utilisez la fonction time_series afin de regrouper les événements par intervalles de 10 secondes et de sommer la valeur body_bytes_sent pour chaque intervalle. Affichez les résultats sur un graphique linéaire en définissant l'axe des x sur time et l'axe des y sur body-sent. Pour plus d'informations, consultez la rubrique Configure the x-axis and the y-axis of a line chart.
* |
select
time_series(__time__, '10s', '%H:%i:%S', '0') as time,
sum(body_bytes_sent) as body_sent
GROUP by
time
ORDER by
time
LIMIT
1000
Interroger le pourcentage de requêtes Tomcat en erreur
Pour déterminer la fraction de toutes les requêtes qui sont des erreurs, calculez le nombre d'erreurs et le nombre total dans une sous-requête à l'aide de l'expression CASE WHEN status >= 400, puis divisez et arrondissez à deux décimales dans la requête externe. Affichez les résultats sur un cadran. Pour plus d'informations, consultez la rubrique Configure a dial.
* |
select
round((errorCount * 100.0 / totalCount), 2) as errorRatio
from
(
select
sum(
case
when status >= 400 then 1
else 0
end
) as errorCount,
count(1) as totalCount
from
log
)