継続は力なり

タイトル通り定期的な更新を心掛けるブログです。

2024年の振り返り

タダです.

2024年も終わりなので,今年の振り返りを行ってきます.

目標の振り返り

本業が忙しすぎてというのは言い訳にしたくなかったのですが,すべて未達でした...来年に持ち越します.

No. 目標概要 アクション 結果
1 自分でWebサービスを開発・運用する Webサービスの開発して運用を1つ以上行う x
2 読み手を意識するアウトプット 月間のPV数を平均7,000超えを目指す x
3 本を年間50冊以上読む 月当たり4冊以上読まないと達成できないが年間で50冊を読んでインプットする x

sadayoshi-tada.hatenablog.com

アウトプットの振り返り

ブログ

今年も PV 数は7000以上を目標にして続けてきていたのですが未達でした.来年も引き続き月平均7000 PV以上を目標にさらに多くの人に見てもらえるようなブログにしていけたらと思います.今年も51記事を書きました.

月 PV 数
1 5678 pv
2 6322 pv
3 6275 pv
4 6250 pv
5 5618 pv
6 5727 pv
7 6648 pv
8 5517 pv
9 6730 pv
10 6498 pv
11 4791 pv
12 4412 pv(12/29時点)

読者数と Twitter のフォロワー数

読者数と Twitter のフォロワー数の推移も増えているのでいい傾向かと思います.来年も自分を知ってもらって興味持ってもらえる方を増やすようにアウトプットをやっていきます.

読者数 Twitter フォロワー 数
119(6人増) 889(89人増)

登壇

2回登壇ができました.そのうち一回は人生初の自主企画イベントもできたのは貴重な経験をさせてもらいました.

まとめ

2024年の一年の振り返りました.今年関わってくれた皆さん本当にありがとうございました!来年もよろしくお願いします!!

過去の振り返り

sadayoshi-tada.hatenablog.com

sadayoshi-tada.hatenablog.com

sadayoshi-tada.hatenablog.com

sadayoshi-tada.hatenablog.com

sadayoshi-tada.hatenablog.com

DuckDB で ALB のアクセスログにクエリしてみる

タダです.

前回 DuckDB で CloudTrail ログを分析してみました.今回は ALB のアクセスログを分析してみます.

sadayoshi-tada.hatenablog.com

sadayoshi-tada.hatenablog.com

ALB アクセスログのテーブルを作る

こちらの記事を参照させていただいてテーブルを作ってみました.

CREATE TABLE alb_log AS
SELECT *
FROM read_csv(
    '[ログファイルパス]',
    columns={
        'type': 'VARCHAR',
        'timestamp': 'TIMESTAMP',
        'elb': 'VARCHAR',
        'client_ip_port': 'VARCHAR',
        'target_ip_port': 'VARCHAR',
        'request_processing_time': 'DOUBLE',
        'target_processing_time': 'DOUBLE',
        'response_processing_time': 'DOUBLE',
        'elb_status_code': 'INTEGER',
        'target_status_code': 'VARCHAR',
        'received_bytes': 'BIGINT',
        'sent_bytes': 'BIGINT',
        'request': 'VARCHAR',
        'user_agent': 'VARCHAR',
        'ssl_cipher': 'VARCHAR',
        'ssl_protocol': 'VARCHAR',
        'target_group_arn': 'VARCHAR',
        'trace_id': 'VARCHAR',
        'domain_name': 'VARCHAR',
        'chosen_cert_arn': 'VARCHAR',
        'matched_rule_priority': 'VARCHAR',
        'request_creation_time': 'TIMESTAMP',
        'actions_executed': 'VARCHAR',
        'redirect_url': 'VARCHAR',
        'error_reason': 'VARCHAR',
        'target_port_list': 'VARCHAR',
        'target_status_code_list': 'VARCHAR',
        'classification': 'VARCHAR',
        'classification_reason': 'VARCHAR',
        'conn_trace_id': 'VARCHAR'
    },
    delim=' ',
    quote='"',
    escape='"',
    header=False,
    auto_detect=False
);
D show tables;
┌─────────┐
│  name   │
│ varchar │
├─────────┤
│ alb_log │
└─────────┘

参考記事

swfz.hatenablog.com

ALB アクセスログの分析クエリを実行する

AWS のドキュメントを参考にクエリをいくつか実行してみます.

クライアント IP アドレス別にグループ分けした HTTP リクエストの数を集計

D SELECT COUNT(request) AS
   count,
   request,
   SPLIT_PART(client_ip_port, ':', 1) as client_ip
  FROM alb_log
  GROUP BY request, client_ip
  ;
┌───────┬──────────────────────────────────────────┬───────────────┐
│ count │                 request                  │   client_ip   │
│ int64 │                 varchar                  │    varchar    │
├───────┼──────────────────────────────────────────┼───────────────┤
│     2 │ GET https://12.34.56.78:443/ HTTP/1.1     │ 123.45.657.89 │
│     1 │ GET https://12.34.56.78:443/xxx HTTP/1.1 │ 45.657.89.110 │
└───────┴──────────────────────────────────────────┴───────────────┘

ELB ステータスコードの値が200以外のリクエストを抽出

SELECT
      type,
      timestamp,
      client_ip_port,
      elb_status_code,
      target_status_code,
      request,
      error_reason
  FROM
      alb_log
  WHERE
      elb_status_code != 200;
┌─────────┬────────────────────────────┬─────────────────────┬─────────────────┬────────────────────┬──────────────────────────────────────────┬──────────────┐
│  type   │         timestamp          │   client_ip_port    │ elb_status_code │ target_status_code │                 request                  │ error_reason │
│ varchar │         timestamp          │       varchar       │      int32      │      varchar       │                 varchar                  │   varchar    │
├─────────┼────────────────────────────┼─────────────────────┼─────────────────┼────────────────────┼──────────────────────────────────────────┼──────────────┤
│ https   │ 2024-12-22 00:35:22.50771  │ 123.45.657.89:12345 │             403 │ -                  │ GET https://12.34.56.78:443/ HTTP/1.1     │ -            │
│ https   │ 2024-12-22 00:35:33.942067 │ 123.45.657.89:53456 │             403 │ -                  │ GET https://12.34.56.78:443/ HTTP/1.1     │ -            │
│ https   │ 2024-12-22 00:36:08.717268 │ 45.657.89.110:32134 │             403 │ -                  │ GET https://12.34.56.78:443/xxx HTTP/1.1 │ -            │
└─────────┴────────────────────────────┴─────────────────────┴─────────────────┴────────────────────┴──────────────────────────────────────────┴──────────────┘

まとめ

DuckDB で ALB のアクセスログを分析するのを試してみました.

DuckDB で CloudTrail のログにクエリしてみる

タダです.

前回 DuckDB CLI をセットアップしました.今回は CloudTrail ログを分析してみます.

sadayoshi-tada.hatenablog.com

S3 に入っているログからテーブルを作る

こちらの記事を参照させていただいてテーブルを作ってみました.

D CREATE TABLE trail_log_20170424 AS
    WITH raw_data AS (
        SELECT *
        FROM read_json(
            's3://[CloudTrail ログパス]',
            maximum_depth=2
        )
    )
    SELECT unnest(Records) AS Event
    FROM raw_data;
D show tables;
┌─────────────────────────────┐
│            name             │
│           varchar           │
├─────────────────────────────┤
│ trail_log_20170427          │
└─────────────────────────────┘

より分析をしやすいようにフィールドを追加したテーブルを用意したらだいぶ見通しが良くなりました.

select * from trail_log_detailed_20170424 limit 10;
┌──────────────┬──────────────────────┬────────────────────┬─────────────────┬────────────────┬───┬─────────────────┬────────────────────┬───────────────┬────────────┬─────────────┬──────────────────────┐
│ eventVersion │      eventTime       │    eventSource     │    eventName    │   awsRegion    │ … │ managementEvent │ recipientAccountId │ eventCategory │ tlsVersion │ cipherSuite │ clientProvidedHost…  │
│   varchar    │       varchar        │      varchar       │     varchar     │    varchar     │   │     varchar     │      varchar       │    varchar    │  varchar   │   varchar   │       varchar        │
├──────────────┼──────────────────────┼────────────────────┼─────────────────┼────────────────┼───┼─────────────────┼────────────────────┼───────────────┼────────────┼─────────────┼──────────────────────┤
│ 1.04         │ 2017-04-27T00:16:43Z │ logs.amazonaws.com │ CreateLogStream │ ap-northeast-1 │ … │                 │ 1234567891011       │               │            │             │                      │
│ 1.04         │ 2017-04-27T00:20:31Z │ logs.amazonaws.com │ CreateLogStream │ ap-northeast-1 │ … │                 │ 1234567891011       │               │            │             │                      │
│ 1.05         │ 2017-04-27T00:20:30Z │ sts.amazonaws.com  │ AssumeRole      │ us-east-1      │ … │                 │ 1234567891011       │               │            │             │                      │
│ 1.04         │ 2017-04-27T00:21:02Z │ logs.amazonaws.com │ CreateLogStream │ ap-northeast-1 │ … │                 │ 1234567891011       │               │            │             │                      │
│ 1.04         │ 2017-04-27T00:26:26Z │ logs.amazonaws.com │ CreateLogStream │ ap-northeast-1 │ … │                 │ 1234567891011       │               │            │             │                      │
│ 1.05         │ 2017-04-27T00:26:25Z │ sts.amazonaws.com  │ AssumeRole      │ us-east-1      │ … │                 │ 1234567891011       │               │            │             │                      │
│ 1.05         │ 2017-04-27T00:26:25Z │ sts.amazonaws.com  │ AssumeRole      │ us-east-1      │ … │                 │ 1234567891011       │               │            │             │                      │
│ 1.05         │ 2017-04-27T00:28:33Z │ sts.amazonaws.com  │ AssumeRole      │ ap-northeast-1 │ … │                 │ 1234567891011       │               │            │             │                      │
│ 1.05         │ 2017-04-27T00:30:38Z │ sts.amazonaws.com  │ AssumeRole      │ us-east-1      │ … │                 │ 1234567891011       │               │            │             │                      │
│ 1.05         │ 2017-04-27T00:33:55Z │ sts.amazonaws.com  │ AssumeRole      │ ap-northeast-1 │ … │                 │ 1234567891011       │               │            │             │                      │
├──────────────┴──────────────────────┴────────────────────┴─────────────────┴────────────────┴───┴─────────────────┴────────────────────┴───────────────┴────────────┴─────────────┴──────────────────────┤
│ 10 rows                                                                                                                                                                            33 columns (11 shown) │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

この中から CreateLogStream のイベントだけ抽出してみます.2017年4月24日のログからは7件見つかりました.古いログすぎてフィールドが一致してなさそうなのですが,CloudTrail のログをスポットで分析する時にどういう操作をしたらいいのかのイメージが付きました.記事を参照させていただき,ありがとうございました!

D select * from trail_log_detailed_20170424 where eventName='CreateLogStream';
┌──────────────┬──────────────────────┬────────────────────┬─────────────────┬────────────────┬───┬─────────────────┬────────────────────┬───────────────┬────────────┬─────────────┬──────────────────────┐
│ eventVersion │      eventTime       │    eventSource     │    eventName    │   awsRegion    │ … │ managementEvent │ recipientAccountId │ eventCategory │ tlsVersion │ cipherSuite │ clientProvidedHost…  │
│   varchar    │       varchar        │      varchar       │     varchar     │    varchar     │   │     varchar     │      varchar       │    varchar    │  varchar   │   varchar   │       varchar        │
├──────────────┼──────────────────────┼────────────────────┼─────────────────┼────────────────┼───┼─────────────────┼────────────────────┼───────────────┼────────────┼─────────────┼──────────────────────┤
│ 1.04         │ 2017-04-27T00:16:43Z │ logs.amazonaws.com │ CreateLogStream │ ap-northeast-1 │ … │                 │ 1234567891011       │               │            │             │                      │
│ 1.04         │ 2017-04-27T00:20:31Z │ logs.amazonaws.com │ CreateLogStream │ ap-northeast-1 │ … │                 │ 1234567891011       │               │            │             │                      │
│ 1.04         │ 2017-04-27T00:21:02Z │ logs.amazonaws.com │ CreateLogStream │ ap-northeast-1 │ … │                 │ 1234567891011       │               │            │             │                      │
│ 1.04         │ 2017-04-27T00:26:26Z │ logs.amazonaws.com │ CreateLogStream │ ap-northeast-1 │ … │                 │ 1234567891011       │               │            │             │                      │
│ 1.04         │ 2017-04-27T01:17:15Z │ logs.amazonaws.com │ CreateLogStream │ ap-northeast-1 │ … │                 │ 1234567891011       │               │            │             │                      │
│ 1.04         │ 2017-04-27T03:18:56Z │ logs.amazonaws.com │ CreateLogStream │ ap-northeast-1 │ … │                 │ 1234567891011       │               │            │             │                      │
│ 1.04         │ 2017-04-27T04:29:09Z │ logs.amazonaws.com │ CreateLogStream │ ap-northeast-1 │ … │                 │ 1234567891011       │               │            │             │                      │
├──────────────┴──────────────────────┴────────────────────┴─────────────────┴────────────────┴───┴─────────────────┴────────────────────┴───────────────┴────────────┴─────────────┴──────────────────────┤
│ 7 rows                                                                                                                                                                             33 columns (11 shown) │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

まとめ

DuckDB で S3 にある CloudTrail のログを分析するのを試してみました.次は ALB のログを試してみたいです.

話題の DuckDB をローカルで実行できる準備を行う

タダです.

今年に入って DuckDB というワードを X やブログ記事を見かける体感が自分の中であり,この期に試してみたいと思っていくつかの記事で試した内容をまとめます.この記事では DuckDB の概要とローカルで実行する準備をします.

DuckDB とは

DuckDB はオープンソースの列指向データベースエンジンで,ローカル環境での分析やクラウドデータの簡単な処理に使用されているのがユースケースです.他には外部データの直接読み込み(S3 や Parquet,CSV など)をサポートしているので,ALB や CloudTrail 等の S3 に入っているログを分析することをやってみたいと思っています.

duckdb.org

github.com

DuckDB のインストール/AWS

そんなわけで DuckDB CLI をインストールしてみます.

$ brew install duckdb
$ duckdb -version
v1.1.3 19864453f7

duckdb コマンドを使って AWS のエクステンションを使用して AWS SDK を叩く前準備を行います.一旦,S3 の CSV ファイルを読み込んでみました.中身が空なのでこれでいいのか..ってなりつつなんですが,他にも試して次以降の記事で書いていきます.

2 ❯ duckdb
[2]  - 10871 continued  duckdb help
D INSTALL aws;
D LOAD aws;
D INSTALL httpfs;
D LOAD httpfs;
D CREATE SECRET (
    TYPE S3,
    KEY_ID 'AKIAIOSFODNN7EXAMPLE',
    SECRET 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
    REGION 'ap-northeast-1'
);
┌─────────┐
│ Success │
│ boolean │
├─────────┤
│ true    │
└─────────┘
D SELECT * FROM read_csv('s3://hoge-bucket/hoge.csv',delim=' ', header=false, ignore_errors=true);
┌─────────┬─────────┐
│ column0 │ column1 │
│ varchar │ varchar │
├─────────┴─────────┤
│      0 rows       │
└───────────────────┘

duckdb.org

duckdb.org

duckdb.org

まとめ

DuckDB を試していくための前準備でセットアップしてみました.

Aurora のバックアップを日次と月次で分けて AWS Backup にて保持する

タダです.

Aurora のバックアップを日次と月次で分けて AWS Backup で保持する設定を行ったので,備忘録としてまとめます.

日次と月次のバックアップジョブ

結論として日次と月次のバックアップジョブを分けて作りました.以下は日次で14日間まで保持するバックアッププランと,毎月1日のバックアップを3ヶ月保持するバックアッププランを作る Terraform のコード例です.

resource "aws_backup_plan" "daily" {
  name = "daily-backup"
  rule {
    rule_name         = "daily"
    target_vault_name = aws_backup_vault.example.name
    schedule          = "cron(0 12 * * ? *)"
    lifecycle {
      delete_after = 14 # days
    }
  }
}
resource "aws_backup_plan" "monthly" {
  name = "monthly-backup"
  rule {
    rule_name         = "monthly"
    target_vault_name = aws_backup_vault.example.name
    schedule          = "cron(0 12 1 * ? *)"
    lifecycle {
      delete_after = 90 # days
    }
  }
}
resource "aws_backup_selection" "daily" {
  name         = "daily-backup"
  plan_id      = aws_backup_plan.daily.id
  iam_role_arn = aws_iam_role.example.arn
  resources    = [
    aws_rds_cluster.example.arn,
  ]
}
resource "aws_backup_selection" "monthly" {
  name         = "monthly-backup"
  plan_id      = aws_backup_plan.monthly.id
  iam_role_arn = aws_iam_role.example.arn
  resources    = [
    aws_rds_cluster.example.arn,
  ]
}

まとめ

Aurora のバックアップを日次と月次で分けて AWS Backup で保持する設定を行ったのでまとめました.