全文検索SaaS「Algolia」のAPI利用状況をログから調べる

全文検索SaaS「Algolia」のGetLogs APIを使ってAPIの利用状況を調べてみた
2022.06.21

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Algoliaは多言語に対応した全文検索SaaSです。使いやすい機能と明瞭な料金体系のため、かんたんにサイト導入できます。

Algoliaの運用を始めると気になるのが、APIの利用状況です。

ダッシュボードを見れば全体的な傾向をつかめますが、検索APIの内訳やエラー内容を確認したい場合は、個別ログを確認するのが手っ取り早いです。 AlgoliaはAPI数課金なのに、気づかずに無駄なAPIをたくさん読んでいた、なんてことになりたくないですしね。

今回は Get Logs API を使って、APIログを取得し、分析する方法を紹介します。

Get Logs API で生ログをログ取得

Algoliaは管理コンソールの API Monitoring メニューから、利用状況や、直近のリクエストの生ログなど、非常に多くの情報を取得できます。

一方で、ユーザーが特定の用途に向けてAPI呼び出しを分析したい場合、生ログを取得するのが確実です。

Get Logs APIを利用すると、過去7日のAPIログを取得できます。

やってみる

Python依存ライブラリを利用

Algolia のAPI実行には、Python SDKを利用します。

依存ライブラリをインストールします。

$ pip install --upgrade algoliasearch pandas

APIキーを作成

Get Logs API を利用するには、 logs ACL が必要です。

デフォルトの Write API キーを利用するか、logs ACL だけを許可した専用のAPIキーを発行しましょう。

Get Logs APIを呼び出す

Get Logs APIを 呼び出します。

from algoliasearch.search_client import SearchClient
client = SearchClient.create('APP-ID', 'KEY')
client.get_logs()

client.get_logs() のデフォルト値を明示する場合、以下の通りです。

client.get_logs({
    // All the following parameters are optional
    'offset' : 0,
    'length': 1000,
    'type' : 'all'
})
  • offset : 0 以上の値を指定し、0 は最新のログです
  • length : オフセットからのログレコード数です。最大は1000です。
  • type : ログの種類を指定します。
    • all : 全て
    • query : 検索
    • build : インデックス・レコード操作
    • erro : エラー

実行すると、以下のような JSON が返却されます。

{
  "logs":[
      {
        "timestamp":"2017-12-29T18:15:57Z",
        "method":"POST",
        "answer_code":"200",
        "query_body":"\n{\n \"requests\": [\n  {\n   \"indexName\": \"best_buy\",\n   \"params\": \"query=&hitsPerPage=10&page=0&attributesToRetrieve=*&highlightPreTag=%3Cais-highlight-0000000000%3E&highlightPostTag=%3C%2Fais-highlight-0000000000%3E&getRankingInfo=1&facets=%5B%22brand%22%2C%22categories%22%2C%22free_shipping%22%2C%22type%22%5D&tagFilters=\"\n  }\n ]\n}\n",
        "answer":"\n{\n \"results\": [\n  {\n   \"hits\": [\n    {\n     \"name\": \"Amazon - Fire TV Stick\",\n     \"description\": \"Amazon Fire TV Stick connects to your TV's HDMI port. Just grab and go to enjoy Netflix, Prime Instant Video, Hulu Plus, YouTube.com, music, and much more.\",\n     \"brand\": \"Amazon\",\n     \"categories\": [\n      \"TV & Home Theater\",\n      \"Streaming Media Players\"\n     ],\n     \"hierarchicalCategories\": {\n      \"lvl0\": \"TV & Home Theater\",\n      \"lvl1\": \"TV & Home Theater > Streaming Media Players\"\n     },\n     \"type\": \"Streaming media plyr\",\n     \"price\": 39.99,\n     \"price_range\": \"1 - 50\",\n     \"image\": \"https:\/\/cdn-demo.algolia.com\/bestbuy\/9999119_sb.jpg\",\n     \"url\": \"http:\/\/www.bestbuy.com\/site\/amazon-fire-tv-stick\/9999119.p?id=1219460752591&skuId=9999119&cmp=RMX&ky=1uWSHMdQqBeVJB9cXgEke60s5EjfS6M1W\",\n     \"free_shipping\": false,\n     \"popularity\": 9843,\n     \"rating\": 4,\n     \"objectID\": \"9999119\"\n",
        "url":"\/1\/indexes\/*\/queries?x-algolia-agent=Algolia%20for%20vanilla%20JavaScript%203.24.7%3BAlgolia%20Dashboard%201.0.0%3Breact-instantsearch%204.1.3%3BJS%20Helper%202.23.0&x-algolia-application-id=AJ0P3S7DWQ&x-algolia-api-key=ce11****************************",
        "ip":"84.14.205.82",
        "query_headers":"Host: c1-de-3.algolianet.com\nConnection: keep-alive\nContent-Length: 308\naccept: application\/json\nOrigin: https:\/\/www.algolia.com\nUser-Agent: Mozilla\/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/63.0.3239.84 Safari\/537.36\ncontent-type: application\/x-www-form-urlencoded\nReferer: https:\/\/www.algolia.com\/apps\/AJ0P3S7DWQ\/explorer\/browse\/best_buy\nAccept-Encoding: gzip, deflate, br\nAccept-Language: fr,en;q=0.9\n",
        "sha1":"44c168cea54d2deca9a4724559cf15eccf15cf3e",
        "nb_api_calls":"1",
        "processing_time_ms":"1",
        "query_nb_hits":"10500",
        "index":"demo_index",
        "inner_queries":[
            {
              "indexName":"best_buy",
              "queryID":313453231,
              "offset":0,
              "userToken":"user_1"
            }
        ]
      }
  ]
}

エラーログを確認

失敗したAPIログだけを取得したい場合、'type':'error' でフィルターします。

from algoliasearch.search_client import SearchClient
from pprint import pprint

client = SearchClient.create('APP-ID', 'KEY')

logs = client.get_logs({
    'type':'error',
})

for log in logs['logs']:
    pprint(log)

出力

{'answer': '\n'
           '{\n'
           '  "message": "Invalid Application-ID or API key",\n'
           '  "status": 403\n'
           '}\n',
 'answer_code': '403',
 'index': 'xxx',
 'ip': '*.*.*.*',
 'method': 'POST',
 'processing_time_ms': '1',
 'query_body': '\n{\n  "query": "test"\n}\n',
 'query_headers': '...',
 'sha1': '2f3a6eefae711cda7fcf0f19f62485a63f0e6239',
 'timestamp': '2022-06-16T09:17:23Z',
 'url': '/1/indexes/xxx/query'}

ログをJSONからCSVに変換

スプレッドシートで分析できるよう、pandas を使い、JSONをCSVに変換して保存します。

import pandas as pd
from algoliasearch.search_client import SearchClient
from urllib.parse import urlparse

client = SearchClient.create('APP-ID', 'KEY')

logs = client.get_logs()
df = pd.DataFrame.from_records(logs['logs'])
df['path'] = df['url'].map(lambda s : urlparse(s).path)

df.to_csv('algolia_logs.csv')

一部のAPIの url フィールドは /1/indexes/xxx/query?x-algolia-agent=Algolia%20for%20JavaScript%20(4.12.1)%3B%20Browser というように GET パラメーターも含まれることがあります。 API を抽出するために、 df['path'] = df['url'].map(lambda s : urlparse(s).path) でURIのパス部のみを抽出しています。

API ごとの呼び出し数を集計

AlgoliaはAPI呼び出し数に応じて課金が発生します。

APIごとにGROUP BYして、API の呼び出し傾向を確認します。

import pandas as pd
from algoliasearch.search_client import SearchClient
from urllib.parse import urlparse

client = SearchClient.create('APP-ID', 'KEY')

logs = client.get_logs()
df = pd.DataFrame.from_records(logs['logs'])
df['path'] = df['url'].map(lambda s : urlparse(s).path)

df_aggr = df.groupby(['path'])['path'].count()
print(df_aggr)

出力

path
/1/indexes/xxx/batch                  31
/1/indexes/xxx/facets/_tags/query     23
/1/indexes/xxx/query                 118
/1/indexes/xxx/rules/search            3
/1/indexes/xxx/settings                1
Name: path, dtype: int64

文字検索とタグ検索の割合がおよそ5:1であるとわかりました。

インデックスを更新する batch も思いの外、呼び出されています。

最後に

Algolia の Get Logs APIを使い、ログを調査・分析する方法を紹介しました。 管理コンソールの API Monitoring では不十分な場合にご活用ください。

API の説明に "Retrieve the logs of your last 1,000 API calls. This helps with real-time debugging of your application." とあったり、ログの保存期間が7日なことからもわかるように、過去をさかのぼったログの調査には向いていません。

そのような要件がある場合、sha1 フィールドをキーに、データベースに永続的に保存すると良いかもしれません。

それでは。

参考