Papertrail Settings APIを叩いてみる

## はじめに

Papertrail API を利用して、ログ管理設定を一括で取得・管理するスクリプトを Ruby で実装し、その取得結果を解説します。

※本記事で扱う Settings API の詳細は公式ドキュメントをご参照ください：  
https://www.papertrail.com/help/settings-api/  

## 目次

1. [スクリプトの概要](#1-スクリプトの概要)
2. [使い方](#2-使い方)
3. [各リソースの詳細](#3-各リソースの詳細)

   1. [searches](#31-searches)
   2. [destinations](#32-destinations)
   3. [users](#33-users)
   4. [accounts](#34-accounts)

## 1. スクリプトの概要

以下のスクリプトは、Papertrail API (`https://papertrailapp.com/api/v1`) から複数リソースの設定情報を取得し、JSON ファイルとして出力します。

```ruby
#!/usr/bin/env ruby
# get_papertrail_settings_with_progress_and_fallback.rb

require 'net/http'
require 'uri'
require 'json'

API_TOKEN = ENV['PAPERTRAIL_TOKEN']
unless API_TOKEN && !API_TOKEN.empty?
  warn "Error: 環境変数 PAPERTRAIL_TOKEN を設定してください。"
  exit 1
end

BASE_URI = 'https://papertrailapp.com/api/v1'

def fetch_settings(resource, max_retries = 3)
  uri = URI("#{BASE_URI}/#{resource}.json")
  attempts = 0
  begin
    attempts += 1
    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = true
    http.open_timeout = 10
    http.read_timeout = 30

    req = Net::HTTP::Get.new(uri)
    req['X-Papertrail-Token'] = API_TOKEN
    req['Accept'] = 'application/json'

    res = http.request(req)
    return JSON.parse(res.body) if res.is_a?(Net::HTTPSuccess)

    warn "  → [#{resource}] HTTP #{res.code} #{res.message}"
    nil
  rescue Net::ReadTimeout, Net::OpenTimeout => e
    warn "  → [#{resource}] Timeout (#{e.class}), attempt #{attempts}/#{max_retries}"
    retry if attempts < max_retries
    warn "  → [#{resource}] Failed after #{attempts} attempts: #{e.message}"
    nil
  rescue => e
    warn "  → [#{resource}] Error: #{e.class} #{e.message}"
    nil
  end
end

resources = %w[searches destinations users accounts]
settings = {}
failed = []

total = resources.size
resources.each_with_index do |res, idx|
  print "Fetching #{res} (#{idx+1}/#{total})... "
  data = fetch_settings(res)
  if data
    settings[res] = data
    puts "OK"
  else
    settings[res] = []
    failed << res
    puts "NG"
  end
end

puts "\nAll done! Retrieved settings for #{total - failed.size}/#{total} resources."
warn "Failed to fetch: #{failed.join(', ')}. See above for details." if failed.any?

puts JSON.pretty_generate(settings)
```

* **認証**: リクエストヘッダーで `X-Papertrail-Token` を渡す
* **タイムアウト設定**: `open_timeout` と `read_timeout` を設定
* **リトライ**: タイムアウト時に最大 3 回まで再試行
* **フォールバック**: 取得失敗時は空配列を代入し、後続で必ず出力

## 2. 使い方

1. 環境変数に API トークンを設定

   ```bash
   export PAPERTRAIL_TOKEN="あなたのAPIトークン"
   ```
2. スクリプトを実行し、JSON をファイルにリダイレクト

   ```bash
   ruby get_papertrail_settings_with_progress_and_fallback.rb > papertrail_settings.json
   ```
3. `papertrail_settings.json` を確認。全リソースの設定情報が JSON 形式で保存されます。

## 3. 各リソースの詳細

### 3.1 searches

* **型**: 配列
* **内容**: Saved Searches の一覧
* **主なフィールド**:

  * `id`: 検索 ID
  * `name`: 表示名
  * `query`: 実行クエリ
  * `group`: { `id`, `name` }
  * `_links`: 各種 API/HTML リンク

---

### 3.2 destinations

* **型**: 配列
* **内容**: ログ転送先設定（syslog）
* **主なフィールド**:

  * `id`: 転送先 ID
  * `filter`: 転送時フィルタ（正規表現）
  * `syslog`: { `hostname`, `port`, `description` }

---

### 3.3 users

* **型**: 配列
* **内容**: Papertrail ユーザー一覧
* **主なフィールド**:

  * `id`, `email`
  * `member`: 権限情報 (`read_only`, `manage_billing` など)
  * `customer`: 顧客設定情報

---

### 3.4 accounts

* **型**: オブジェクト
* **内容**: アカウント利用状況と制限
* **主なフィールド**:

  * `log_data_transfer_used`: 転送済みログ量（バイト）
  * `log_data_transfer_used_percent`: 使用率（％）
  * `log_data_transfer_plan_limit`: プラン上のソフトリミット（バイト）
  * `log_data_transfer_hard_limit`: ハードリミット（バイト）

## 追記
※なお、同様の方法で `groups` や `systems` のエンドポイントを取得しようとすると、レスポンスが遅くタイムアウトによりうまく取得できないため、本サンプルではリソースリストから除外しています。