Quantcast
Channel: プログラミング
Viewing all articles
Browse latest Browse all 7970

Deno KVでアクセスログ的なものを記録する - notebook

$
0
0

Deno KVを活用してDeno deployにホストしたサービスのアクセスログを記録する

目的は公開しているサービスの利用状況をしっかり確認したかったというところから、アクセスログ記録するかという流れ

もともとやりたいとは思っていたがぐだぐだしていたらかなり時間が経ってしまった

とりあえず取れる情報はすべて取っておきたいのでrequestオブジェクトの内容はすべて記録するようにした

Denoサーバ側の実装

簡単な例

  • logger.ts
import{ ulid }from"jsr:@std/ulid";

const EXPIRE_LOGS_DAYS = 90;

const logObject = async (now:Date, req:Request)=>{const ts = Math.floor(now.getTime() / 1000);

  return{method: req.method,
    url: req.url,
    redirect: req.redirect,
    bodyUsed: req.bodyUsed,
    ...{ts: ts },
    headers: Object.fromEntries(req.headers.entries()),
    ...(req.body ? {body: await req.text() } : {}),
  };
};

const log = async (request:Request, additionalData)=>{const kv = await Deno.openKv();
  const now = newDate();
  const logRecord = { ...(await logObject(now, request)), ...additionalData };

  returnawait kv.set(["logs", now.getFullYear(), now.getMonth() + 1, now.getDate(), ulid()], logRecord, {expireIn: 1000 * 60 * 60 * 24 * EXPIRE_LOGS_DAYS,
  });
};

export{ log };

キーの値は['logs', 2024, 9, 17, '01J81GWK767S8Y6THBEP1Y6V6T']といった感じの内容となる

毎度使うパラメータや重要な指標などを含めておけるよう、logを呼び出す際に第2引数でオプショナルなデータを追加できるようにした

  • server.ts
import{ log }from"./logger.ts";  
  
const port = 8080;  
  
const handler = async (request:Request):Promise<Response>=>{// ...何かしらの処理

  log(request, {});  
  
  // ...何かしらの処理returnnewResponse('message', {status: 200});
};  
  
console.log(`HTTP webserver running. Access it at: http://localhost:8080/`);  
Deno.serve({port }, handler);

これでサービスへのアクセス時の情報がKVに記録される

永続的なデータ保存

KVからGCSやS3へのExportでもよいかと思ったけど

アクセスキーを発行してDeno Deploy側に保存しないといけないのか…と思ったので

記録はKVにして(Expire指定)GoogleCloudやGitHubActionsなどからKVへアクセスして参照、ExportしてBigQueryへ取り込むのが良さそうということでそうした

Deno側のアクセスキーが必要となるが保存先はGitHubかGoogleCloudになる

logviewer

実際にBigQueryへ取り込む前にサーッと中身みたいなと思ったので簡単なCLIを書いた

swfz/deno-kv-logviewer

github.com

出力するキーはオプションで指定可能にしたので用途によって使い分けできるはず

とりあえず自分が使う分には不自由していない

--jsonオプションを用意したのでExportするときはJSON形式で出力してbq loadするだけみたいなのがサクッとできる

サンプルイメージ

{id}の箇所の値はDeno DeployのProjectのKVタブから取得する

ザーッと眺めてみるパターン

$ deno run --allow-net --allow-env --unstable-kv logviewer.ts --url=https://api.deno.com/databases/{id}/connect --prefix=logs,2024,9 --exclude=headers,value,versionstamp,bodyUsed,redirect,ua

┌───────┬──────────────────────────────────────────────────────┬────────┬─────────────────────────────────────────────────────────────┬────────────────────────────┬────────────┬──────────────┬─────────┬────────────────────────────────┐
│ (idx) │ key                                                  │ method │ url                                                         │ ts                         │ user       │ to           │ theme   │ referer                        │
├───────┼──────────────────────────────────────────────────────┼────────┼─────────────────────────────────────────────────────────────┼────────────────────────────┼────────────┼──────────────┼─────────┼────────────────────────────────┤
│     0 │ [ "logs", 2024, 9, 5, "01J70480GF97GVKTQ4JTV7NERY" ] │ "GET"  │ "https://kusa-image.deno.dev/swfz"                          │ "2024-09-05T03:39:28.000Z" │ "swfz"     │ undefined    │ "light" │ undefined                      │
│     1 │ [ "logs", 2024, 9, 5, "01J70487J7CQ32WXK8R973SP9A" ] │ "GET"  │ "https://kusa-image.deno.dev/swfz?to=2023-01-01"            │ "2024-09-05T03:39:35.000Z" │ "swfz"     │ "2023-01-01" │ "light" │ undefined                      │
│     2 │ [ "logs", 2024, 9, 5, "01J7048CAKF7P2W9ZE4QM75B6V" ] │ "GET"  │ "https://kusa-image.deno.dev/swfz?to=2023-01-01&theme=dark" │ "2024-09-05T03:39:40.000Z" │ "swfz"     │ "2023-01-01" │ "dark"  │ undefined                      │                                                                                                  ```

console.tableでこんなによしなに出力してくれるの知らなかったのでちょっとびっくりした

実際に眺めてみて

Kusa Imageterminal-imageで使っている

ほぼ自分だけが利用者って感じだったがごく少数だけどGitHubのREADMEに貼り付けたりしてくれている人がいた

利用されていることがわかったので良かった、励みになる

あとはterminal-imageの方はSlackのImageProxyというUserAgentからアクセスがちょいちょいあってどこかで共有されているのか?という感じでちょっとテンションが上った

作ってすぐのころはブログに書いて宣伝もしていたので、もしかしたらもうちょい使ってもらえてたかもしれないと考えると最初から入れておけばよかったと後悔している

まとめ

  • Deno Deployで動いているサービスのアクセスログをKVへ保存した
  • KVの中身を簡単に見るためのDenoスクリプトを書いた
  • 意外と作ったサービスを使ってくれている人もいることがわかって良かった

Viewing all articles
Browse latest Browse all 7970

Trending Articles