Jak profilovat Web API

Připravili jsme pro vás postup, jak získat data pro profilovací nástroj ABRA Gen z Web API požadavků.

API je možné profilovat pomocí ABRA Gen profileru globálně anebo jen konkrétní dotaz. Vždy je ale možné mít spuštěný profiler jen jednou (z hlediska ABRA Gen se jedná o globální zdroj).

Předpoklady

  • Profilování budeme testovat na spojení s názvem demodata.
  • V konfiguračním souboru Nexus.CFG máme v sekci [Client] nastavenou hodnotu parametru Local na 0.
  • Ve spojení demodata bude uživatel Supervisor, který bude mít zatržen parametr Přhlášení nevizuálního uživatele API.
  • Bude spuštěn aplikační server.

Globální profilování

Globální profilování

Globální profilování profiluje všechno v době, kdy je profiler spuštěný. Pro jeho použití je nutné mít přidělené právo Spouštět a zastavovat globální profilování.

  • GET /maintenance/profiler/status - vrátí stav profileru (enabled/disabled)
  • POST /maintenance/profiler/start - spustí profiler
  • POST /maintenance/profiler/stop - zastaví profiler a vrátí binárně soubor s profilovanými daty

Při zastavení profileru příkazem `/maintenance/profiler/stop` je vrácen binárně soubor s profilovanými daty. Předpokládá se, že tento soubor uložíme s koncovkou .ap. Následně jej pak lze otevřít v ABRA Gen Profileru (nástroj je možné vyvolat v rámci systému ABRA Gen klávesovou zkratkou Ctrl+Alt+Shift+F12).

Příkaz `stop` podporuje nepovinný parametr filename, pomocí kterého je možné nastavit filename v hlavičce Content-Disposition.

Dále podporuje nepovinný parametr datamode s hodnotami `binaryprofdata` a `jsonprofdata`, pomocí kterého je možné vrátit data profileru binárně nebo ve formátu json.

Spuštění globálního profilování:

POST http://localhost:80/demodata/maintenance/profiler/start

Zastavení globálního profilování (a stažení dat):

POST http://localhost:80/demodata/maintenance/profiler/stop

Zjištění stavu globálního profilování:

GET http://localhost:80/demodata/maintenance/profiler/status

Příklad v Pythonu pro globální profilování:

import base64
import tempfile
import assertpy
import requests

session = requests.Session()
headers = {}
headers['Content-Type'] = 'application/json'
headers['Authorization'] = "Basic " + (
    base64.urlsafe_b64encode(("tester" + ":" + "testerp").encode("utf-8"))
).decode("utf-8")

# start profiler
response = session.post(
    url="http://localhost:80/demo/maintenance/profiler/start", headers=headers
)
assertpy.assert_that(response.status_code).is_equal_to(200)
print("Profiler spuštěn.")

# do some stuff
for _ in range(10):
    response = session.get(
        url="http://localhost:80/demo/countries?select=ID&where=ID+eq+'00000CZ000'",
        headers=headers,
    )
    assertpy.assert_that(response.status_code).is_equal_to(200)
print("Provedeny profilované dotazy.")

# you can check if running if you want
response = session.get(
    url="http://localhost:80/demo/maintenance/profiler/status", headers=headers
)
assertpy.assert_that(response.status_code).is_equal_to(200)
print(f"Is profiler running: {response.content.decode('utf-8')}")


# stop profiler and get back results(saved file can be opened by abra ProfilerViewer.exe)
response = session.post(
    url="http://localhost:80/demo/maintenance/profiler/stop", headers=headers
)
assertpy.assert_that(response.status_code).is_equal_to(200)
with tempfile.NamedTemporaryFile(suffix=".ap", delete=False) as file:
    file.write(response.content)
    print(f"Profiling file saved here: {file.name}")

Profilování jednoho dotazu

Profilování jednoho dotazu

Profilování jednoho dotazu Web API probíhá tak, že se za dotazovaný endpoint přidá obecný parametr profiling=1 (nebo `profiling=true`).

Aby toto profilování fungovalo, je třeba nejdřív v konfiguraci api serveru APIServer.yaml odkomentovat a nastavit parametr profilePath, kam se budou ukládat data získaná z profilování. Například:

#  path where some profile files are stored(f.e. by using of profile parameter)
  profilePath: c:\ABRA_24.2\APILogs\Profiler\

Cílový adresář musíme založit ručně.

Požadavek s parametrem `profiling=1` vrátí v odpovědi hlavičku X-Request-ID. V názvech souborů uložených v `profilePath` je použita právě tato hlavička.

Profilovaná data je možné následně stáhnout pomocí endpointu GET /maintenance/profiler/results s parametrem id (jehož hodnota je `X-Request-ID` z profilovaného dotazu).

Stažená binární data lze pak po uložení otevřít v ABRA Gen Profileru (nástroj je možné vyvolat v rámci systému ABRA Gen klávesovou zkratkou Ctrl+Alt+Shift+F12).

Endpoint `/maintenance/profiler/results` podporuje nepovinný parametr filename, pomocí kterého je možné nastavit název souboru v hlavičce Content-Disposition.

Dále podporuje nepovinný parametr datamode s hodnotami `binaryprofdata`, `jsonprofdata` a `all`. Pro hodnotu `all` se vrátí zip archiv obsahující všechny soubory (profilovací data v binárním a json formátu, request i response).

Profilování číselníku zemí:

GET http://localhost:80/demodata/countries?take=10&profiling=1

Odpověď vrátí hlavičku, např.: `X-Request-ID: API_695b476e497a4662aeb6f67745b99fdd`.

Tuto hlavičku použijeme jako parametr pro stažení dat:

GET http://localhost:80/demodata/maintenance/profiler/results?id=API_695b476e497a4662aeb6f67745b99fdd

Stažení všech dat v zip archivu:

GET http://localhost:80/demodata/maintenance/profiler/results?id=API_695b476e497a4662aeb6f67745b99fdd&datamode=all

Příklad v Pythonu pro profilování jednoho dotazu:

import base64
import tempfile
import assertpy
import requests

session = requests.Session()
headers = {}
headers['Content-Type'] = 'application/json'
headers['Authorization'] = "Basic " + (
    base64.urlsafe_b64encode(("tester" + ":" + "testerp").encode("utf-8"))
).decode("utf-8")

# run request with enabled profiling
response = session.get(
    url="http://localhost:80/demo/countries?select=ID&where=ID+eq+'00000CZ000'&profiling=1",
    headers=headers,
)
assertpy.assert_that(response.status_code).is_equal_to(200)
print("Proveden jeden profilovaný dotaz.")

# get profiled data
x_request_id = response.headers["X-Request-ID"]
print(f"Získáno X-Request-ID: {x_request_id}")

# Příklad 1: Stažení výchozího binárního souboru (.ap)
response_prof = session.get(
    url=f"http://localhost:80/demo/maintenance/profiler/results?id={x_request_id}",
    headers=headers,
)
assertpy.assert_that(response_prof.status_code).is_equal_to(200)
with tempfile.NamedTemporaryFile(suffix=".ap", delete=False) as file:
    file.write(response_prof.content)
    print(f"Profiling file (.ap) saved here: {file.name}")

# Příklad 2: Stažení všech dat jako zip archiv
response_zip = session.get(
    url=f"http://localhost:80/demo/maintenance/profiler/results?id={x_request_id}&datamode=all",
    headers=headers,
)
assertpy.assert_that(response_zip.status_code).is_equal_to(200)
with tempfile.NamedTemporaryFile(suffix=".zip", delete=False) as file:
    file.write(response_zip.content)
    print(f"Profiling file (.zip) saved here: {file.name}")