Yeniden eskiye sayili sayfali verinin tamamina erismek

Bir is icin, sentry’deki¹ trace’lerimizin tamamini indirmek, ve zaman icinde indirmeye devam edip guncel tutmak gerekti. Fakat API’leri² bunu kolaylastiracak sekilde tasarlanmamis.

Basit bir cozum urettim, su anda calisiyor. Alternatiflerle ilgili beyin firtinasi yapmak istedim, buraya yazayim dedim.

Trace listeleme API’si cok basit:

  • GET {org}/traces/ → Son 100 trace’i veriyor. Header’larda next/prev linki var³:
  • GET {org}/traces/?&cursor=0:100:0 → “Siradaki” 100 trace’i, yani son 101.~200. trace’i veriyor. Header’da next/prev var:
  • GET {org}/traces/?&cursor=0:200:0 → …

Gelen data bana ait olmadigi icin ornek veremeyecegim, fakat soyle ozetleyeyim:

{
  "data": [
    {
      "trace": "0123456789abcdef0123456789abcdef", (unique ID, hex)
      "start": 1764674600,                         (unix timestamp)
      ...
    },
    {
      "trace": "1123456789abcdef0123456789abcdf0",
      "start": 1764674590,
      ...
    },
    ... (Toplam 100 adet)
  ]
}

Gunde 3-4 kere calisip son 8-6 saatteki trace’leri isleyecek bir script yazdim/gerekiyor.

Cozumleri kolaylastiracak seyler:

  • Her trace’in unique ID’si var
  • Her trace’in asagiya ve ileri sayfaya gittikce azalan timestamp’i var
  • Sayfa link’leri her zaman 0:N00:0 seklinde. Yani aslinda istenen bir sayfaya atlamak mumkun.
  • Hatta 0:X:0 ile X. ila X+99. siradaki trace’lere erismek mumkun
  • Geriye yonelik linkler var, ve 0:N00:1 seklindeler. “1” neye yariyor, anlamadim.
  • Linklerin yaninda sayfanin bos olup olmadigi da veriliyor.

Cozumleri zorlastiracak seyler:

  • Cok sayfa var. Su aralar 1000 tane filan. Bastan sonra gitmesi yarim saati bulabiliyor.
  • Yeni trace’ler olustukca sayfalarin kaydigini varsayiyorum.

Akliniza guzel cozumler geliyor mu?


1: Evet, o firma. Link vermek istemedim.
2: Aslinda “api documentation” diye aratinca cikiyor.
3: API dokumentasyonunda “Paginating Results” diye bir kisim var

1 Beğeni

Merhaba;

Öncelikle belirtmek isterim sentry’e hakim değilim. Konunuz üzerine biraz dokümantasyon incelemesi yaptım.

anladığım kadarı ile sentry cursor bazlı sayfalama yapıyor. Döndüğü cursor A:B:C tamamen opak yapıda, position:offset:direction pointerlari anlamında verilmiş ama semantik bir veri yapısı ifade etmiyor. Kullanıcı prev ve next page cursorlarını kullanmalı. Manuel cursor oluşturmak bizi istediğimiz sonuca ulaştırmayacak buna dikkat etmek gerek. Github issueları biraz tararsan bu konu baya tartısılmış

?&cursor=0:100:0 buradaki cursor her zaman bize sentry’nin verdiği cursor olmalı. Bunu manuel olarak yazmak bizi doğru veri setine götürmeyecek. Zaten bu kısmı fark etmişsinizdir.

belki ihtiyacınız olan şey Search ?query kısmı olabilir. Belirli bir takım trace’i ön eleyebilirsiniz.

Bütün verileri tüketmek için

  1. initial isteği at
  2. next cursoru varsa cursor ile tekrarlamaya devam et
  3. dönen bütün sonuçları bir öncekinin önüne append et
#!/usr/bin/env bash
set -euo pipefail

BASE_URL="$SENTRY_BASE_URL"
ORG="$ORG_SLUG"
TOKEN="$AUTH_TOKEN"
OUT="${1:-traces.ndjson}"
QUERY="${TRACES_QUERY:-}"

: > "$OUT"

cursor=""

while true; do
    url="${BASE_URL}/api/0/organizations/${ORG}/traces/"
    [ -n "$QUERY" ] && url="${url}?${QUERY}"
    [ -n "$cursor" ] && url="${url}&cursor=${cursor}"

    headers=$(mktemp)
    body=$(mktemp)

    curl -sS -H "Authorization: Bearer $TOKEN" -D "$headers" -o "$body" "$url"

    tmp=$(mktemp)
    jq -c '.[]' "$body" > "$tmp"

    cat "$tmp" "$OUT" > "${OUT}.new"
    mv "${OUT}.new" "$OUT"

    next=$(grep -i '^Link:' "$headers" | tr ',' '\n' | grep 'rel="next"' || true)
    [ -z "$next" ] && break
    res=$(echo "$next" | grep -o 'results="[^"]*"' | cut -d'"' -f2)
    [ "$res" != "true" ] && break
    cursor=$(echo "$next" | grep -o 'cursor="[^"]*"' | cut -d'"' -f2)
    [ -z "$cursor" ] && break

    rm -f "$headers" "$body" "$tmp"
done

İyi çalışmalar, saygılar;

100 trace’in boyutu ne kadar? Acaba daha fazla sayıda çekmek hatta hepsini çekmek mümkün mü diye düşündüm, daha basit olurdu. Mesela günde bir çalışıp 24 saatlik veriyi çekemez mi, çok mu büyük olur veri boyutu? Bu arada API ile zamana göre trace getirilebiliyor mu?

Merhaba @ismailarilik hocam;

Cursor bazlı bir pagination yapısı kullanmışlar.
Her endpoint sabit bir limit/offset değil, tamamen cursor token üzerinden ilerliyor.
Bu yüzden:

  • Toplam kaç kayıt olduğu
  • Kaç sayfa olduğu
  • Son sayfa numarası gibi bilgiler response içerisinde gelmiyor.

Sadece varsa:

  • next_cursor
  • previous_cursor

alanları dönüyor.

Yani pagination modeli sadece “ileri/geri devam edebiliyorsan et” şeklinde çalışıyor.

Filtreleme açısından neyseki belirli bir zaman aralığı, belirli trace tipleri, belirli severity’ler için filtreler gönderebiliyorsun.

API sana sadece “devam edebilirsin” diyor, sayfa sayısı veya toplam entry bilgisi vermiyor.

Benim yukarıda oluşturmak istediğim çözüm de aslında sizin yaklaşımınıza oldukça benzerdi:

  • Tüm API’yi cursor bitene kadar tüket

  • Gelen her sayfayı — sırayla — tek bir dosyaya append et

En azından son gelen veri en üstte olacak şekilde birleşik bir çıktı elde edilebilir. Ben olsam böyle yapardım, Bunu bir cron’a bağlayıp belli aralıklarla çalıştırtırdım.

Arkadaşın çözümü nedir onuda merak ediyorum.