OmniAICreator/Qiita-1.07M huggingface dataset:
ECS TaskからStep Functionsへのタスク完了通知（sendTaskSuccess）の実装


# はじめに
ECSタスクからStep Functionsへタスク完了を通知し、ECSタスクの実行結果を受け取る実装について確認します。
[参考記事](https://xp-cloud.jp/blog/2023/04/21/162737)
AWS CDKを使用したインフラストラクチャのコード化（IaC）の例も含めて説明していきます。

# システム概要

以下のようなアーキテクチャを実装します：

1. Step Functionsがタスクトークンを含むECSタスクを起動
2. ECSタスク内のPythonアプリケーションが処理を実行
3. 処理完了後、タスクトークンを使用してStep Functionsに完了通知を送信

# 実装のポイント

## 1. タスクトークンの受け渡し

### Step Functions側の設定（CDK）

```typescript
const runTask = new stepfunctions_tasks.EcsRunTask(this, 'Run ECS Task', {
  integrationPattern: stepfunctions.IntegrationPattern.WAIT_FOR_TASK_TOKEN,
  cluster: cluster,
  taskDefinition: taskDefinition,
  launchTarget: new stepfunctions_tasks.EcsFargateLaunchTarget(),
  containerOverrides: [
    {
      containerDefinition: container,
      environment: [
        { name: 'TASK_TOKEN', value: stepfunctions.JsonPath.taskToken }
      ],
    },
  ],
});
```

ポイント：
- `IntegrationPattern.WAIT_FOR_TASK_TOKEN`を指定
- コンテナの環境変数として`TASK_TOKEN`を渡す

## 2. ECSタスクへの権限付与

```typescript
// Add StepFunctions permissions to the task role
taskDefinition.addToTaskRolePolicy(
  new iam.PolicyStatement({
    effect: iam.Effect.ALLOW,
    actions: [
      'states:SendTaskSuccess',
      'states:SendTaskFailure'
    ],
    resources: ['*']
  })
);
```

ポイント：
- ECSタスクロールにStep Functionsへの権限を追加
- `SendTaskSuccess`と`SendTaskFailure`の両方の権限を付与

## 3. タスク完了通知の実装（Python）

```python
import os
import boto3
import json

def main():
    # 処理の実行
    result = {"message": "Task completed successfully", "data": 42}
    
    # Step Functionsにタスク完了を通知
    sfn_client = boto3.client('stepfunctions')
    sfn_client.send_task_success(
        taskToken=os.environ['TASK_TOKEN'],
        output=json.dumps(result)
    )

if __name__ == '__main__':
    main()
```

ポイント：
- 環境変数から`TASK_TOKEN`を取得
- `boto3`を使用してStep Functionsクライアントを初期化
- `send_task_success`で完了通知と結果を送信

# エラーハンドリング

エラーが発生した場合は`send_task_failure`を使用して失敗を通知することができます：

```python
try:
    # 処理の実行
    result = process_task()
    sfn_client.send_task_success(
        taskToken=os.environ['TASK_TOKEN'],
        output=json.dumps(result)
    )
except Exception as e:
    sfn_client.send_task_failure(
        taskToken=os.environ['TASK_TOKEN'],
        error='TaskProcessingError',
        cause=str(e)
    )
```

# 実行結果の受け取り
Step FunctionsでECSのタスクの実行結果は以下のように`状態の出力`欄で確認できます。

![ecs-task-result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/9b3b0fa4-d501-4639-a955-ba2393254139.png)

# まとめ

この実装により、以下のメリットが得られます：

1. 非同期処理：Step Functionsは処理完了を待機できる
2. 柔軟な結果通知：成功/失敗の両方のケースに対応
3. IaCによる管理：CDKで権限やインフラを一元管理

Step FunctionsでECSのタスクの実行結果を受け取ることで、ECSの実行結果を後続処理で利用したい場合があると思いますが、
上記のような実装を行うことで、実現できると思います。

# 参考文献
- [Step Functions SendTaskSuccess](https://docs.aws.amazon.com/ja_jp/step-functions/latest/apireference/API_SendTaskSuccess.html)
- [Step FunctionsでECSのタスクの実行結果を受け取る](https://xp-cloud.jp/blog/2023/04/21/162737)
材料力学「単位荷重法の積分公式を教えて下さい。」をAI先生に聞きました。

**・おすすめのwebページを探しています。よろしくお願いします。**

(???紆余曲折の末)途中省略
```
# 質問リスト
1. 単位荷重法の変位計算において、曲げモーメント図の積分では、台形・三角形・パラボラ形の組み合わせが重要になります。  
   以下に、考えられるすべての組み合わせと、それぞれの積分結果をまとめます。
2. 本当ですか
3. 三角形と三角形で
4. 上記をsympyのソースコードで教えて下さい。
```
# ChatGPT先生へ
???**(回答抜粋)難しい。私は、これから勉強が必要です。**

```
上記をmatjaxのソースコードで教えて下さい。
```
```math
\[
I = \int_0^L M_1(x) M_2(x) dx
\]

\[
M_1(x) = M_{1, \text{max}} \frac{x}{L}, \quad M_2(x) = M_{2, \text{max}} \frac{x}{L}
\]

\[
I = \int_0^L \left( M_{1, \text{max}} \frac{x}{L} \right) \left( M_{2, \text{max}} \frac{x}{L} \right) dx
\]

\[
I = M_{1, \text{max}} M_{2, \text{max}} \int_0^L \frac{x^2}{L^2} dx
\]

\[
I = M_{1, \text{max}} M_{2, \text{max}} \cdot \frac{1}{L^2} \int_0^L x^2 dx
\]

\[
I = M_{1, \text{max}} M_{2, \text{max}} \cdot \frac{1}{L^2} \cdot \frac{L^3}{3}
\]

\[
I = \frac{1}{3} M_{1, \text{max}} M_{2, \text{max}} L
\]
```

```python
import sympy as sp

# 変数の定義
x, L = sp.symbols('x L', real=True, positive=True)
M1_max, M2_max = sp.symbols('M1_max M2_max', real=True, positive=True)

# 三角形のモーメント分布
M1 = M1_max * (x / L)
M2 = M2_max * (x / L)

# 積分の計算
I = sp.integrate(M1 * M2, (x, 0, L))

# 結果の表示
sp.pprint(I)
```

# Gemini先生へ

# copilot先生へ

# いつもの? sympyの実行環境と 参考のおすすめです。
[(テンプレート)](https://qiita.com/mrrclb48z/items/00dd08b0317069be9342)
# いつもと違うおすすめです。

#### wikipedia 
#### Qiita
#### Google検索
#### 文献
・旧い本です。
青木徹彦 『構造力学（土木系 大学講義シリーズ 5）』（コロナ社、1986年）200頁 など
https://www.coronasha.co.jp/np/isbn/9784339050448/
【備忘録】AWS RDS概要 + 構築手順

# RDS概要
**マネージド(ほぼ全部をAWSが管理する)DBのAWSリソース
DBエンジンを複数種類から選べる**

### Aurora
MySQL・PostgreSQLと互換性のあるRDB**
MySQLの5倍・PostgreSQLの3倍**処理性能が高い
3AZに6つデータをコピーするので耐障害性に優れる**

### RDSのデメリット
**DBエンジンのバージョンはAWSが提供している物しか選べない
DBインスタンスのスペックに上限がある
DBインスタンスのOSにログインできない**

### パラメータグループ・オプショングループ
**パラメータグループ:DBエンジンの設定を管理する機能
オプショングループ:DBエンジン毎に用意されている追加機能の管理**

### マルチAZ配置
別のAZに**スタンバイインスタンス**としてRDSを作成しておき、**プライマリインスタンス**のRDSと同期させておくことで、障害発生時に**スタンバイインスタンスにフェイルオーバーする**構成
**フェイルオーバーの仕組み
アプリはRDSのドメインを指定する、障害発生時にドメインに紐づくIPアドレスをAWS側が勝手に変更することで動作する**

### リードレプリカ
**読み取り専用**のDBインスタンス

### DBサブネットグループ
DBインスタンスを配置するサブネットを指定する設定
DBインスタンス作成前に作成する
最低でも2AZ以上のサブネットを登録する必要がある

### スナップショット・リストア
**スナップショット:DBインスタンスのバックアップ
リストア:スナップショットからDBインスタンスを作成すること**

### リネーム
DBインスタンスのドメイン名を変更すること
リストアと合わせて活用することで、アプリ側で変更せずにDBインスタンスを変更出来る

## RDS構築手順
**1.セキュリティグループの作成
2.サブネットグループの作成**
**3.パラメータグループの作成
4.RDSインスタンスの構築**

**1-1.セキュリティグループ名・属するVPC・MySQLのポートを送信元をWebサーバに指定して作成**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/18b29bc7-44cb-4d85-ac8d-d86f7335c376.png)

**2-1.サブネットグループ名・属するVPC・AZ・サブネットを指定して作成**
![image 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/0dc36dfd-2e2b-4b0c-9d3a-bffe792ef6a7.png)

**3-1.パラメータグループ名・DBエンジンのタイプ・パラメーターグループファミリーを指定する**
![image 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/419cea0c-e40c-4852-80e5-25b731666388.png)

**4-1.DBのエンジンタイプ・テンプレート→無料利用枠・DBインスタンス識別子・マスターパスワード・属するVPC・DBサブネットグループ・セキュリティグループ・AZ・追加設定→DBパラメータグループを指定する**
![image 3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/022ddf53-9694-4d7c-82a0-2d2a68a817f8.png)
【備忘録】AWS ELB(ALB)概要 + 構築手順

# ELB

**トラフィックを分散**してサーバに送るAWSリソース

複数のAZを跨いで分散する場合、内部的には各AZにELBが配置されることになる
ELB自体の負荷が高い時自動でスケールアップする

### ELBの種類
- ALB(レイヤー7)
- NLB(レイヤー4)**

### パスベースルーティング(ALB)
URLのパス**によってトラフィックを送るサーバを決定する

### スキーム
**インターネット向けはインターネットから通信可能
内部はインターネットから通信不可**

### リスナー
**受け付ける通信の設定とどのサーバに通信を転送させるのかの設定
受け付ける通信はHTTP・HTTPSを指定する
転送先はターゲットグループを使用する**

### AZとサブネット
**インターネット向けを選択した場合は、publicサブネットを選択する必要がある**
**ALBが自動でスケールアウトした時にサブネットのIPを使用する**ので、ALBが配置されるサブネットに8つ以上のIPをALBが使える状態にしておくことがベストプラクティス

### ターゲットグループ
**負荷分散の対象サーバをまとめたグループのこと**
**対象サーバ単体をターゲットと呼ぶ**

### ヘルスチェック
**ターゲットが正常に稼働しているかリクエストを送ること**
**正常に稼働していればトラフィックを捌けるとALBが判断する**

### スティッキーセッション
**同じユーザからのリクエストを同じターゲットに転送する機能**
**Cookie**を使って識別している

## ELBの構築手順
**1.ELBを作成する
2.EC2インスタンスのセキュリティグループを変更する
4.既存のEC2インスタンスを削除する**

**1-1.ALBを作成をクリック**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/55801a81-5414-4a1a-9d25-3020753a4729.png)

**1-2.ターゲットグループを作成する
ターゲットタイプ・ターゲットグループ名・プロトコル・インスタンスが配置されたVPCを選択**
![image 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/f67abc32-7a05-4b38-9bea-dde8f2007bc1.png)
![image 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/c034c283-032b-42ce-be41-7ec7e980fc30.png)

**1-3.ターゲットインスタンスを指定する**
![image 3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/b50f74a4-57c9-4e0b-9822-84afd4a9efe3.png)

**1-4.スティッキーセッションの設定を行う
ターゲットグループ→属性→維持設定をオンにするをクリックする**
![image 4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/8be835c7-9a1c-4e1e-b8be-a74a4e602cc7.png)

**1-5.LB名・スキーム・LBを配置するサブネット・セキュリティグループ・リスナー・ターゲットグループを指定する**
![image 5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/fff06cd7-d62d-4d0e-b1be-e93c7b55d4a1.png)
![image 6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/ac4b0417-7c8b-42d8-86c8-60ec4537ff6b.png)
![image 7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/3f40ddff-07ec-4d21-8f96-3795e28fcedc.png)

**1-6.LBが正常に作成されましたと表示されればOK**
![image 8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/8502b207-feed-49c8-bba0-dd40dc0b3252.png)

**2-1.EC2インスタンスのHTTPリクエストの許可をALBからのみに変更する**
![image 10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/a8eca17e-1b4c-4303-ad00-60f2a7467f9d.png)
【備忘録】AWS NAT Gateway概要 + 構築手順

# NAT Gateway

### **NAT**
**プライベートIP**を**パブリックIP**に変換する技術
**プライベートIPからパブリックIPに変換は出来るが、逆は出来ない(一方通行)
プライベートサブネットのEC2からインターネットに接続出来る
用途
セキュリティパッチ・ソフトウェアアップデートのために使用する**

### NAT Gateway
NAT**機能を提供する**AWSリソース
サブネット** + **EIP** を指定するだけで作成出来る

## NAT Gateway構築手順
**1.NAT Gatewayを作成する
2.プライベートサブネット用ルートテーブルの作成**

**1-1.NAT Gatewayの名前・パブリックサブネット・EIPを選択する**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/d88baddd-27fe-4b99-9a87-0b4f8de96b3d.png)

**1-2.NAT ゲートウェイが正常に作成されましたと表示されればOK**
![image 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/618da88a-4744-4e1e-ae53-bfebabf87df0.png)

**2-1.ルートテーブル名・VPCを選択する**
![image 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/061cba49-5412-4016-b2c7-17a38b07f42d.png)

**2-2.作成したルートテーブルのルーティングにNATゲートウェイを選択する**
![image 3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/2a922533-63e9-404e-820a-dc8f063a9325.png)

**2-3.ルートテーブルをサブネットに紐づける**
![image 4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/490a4b10-214a-4b32-96e4-a05b97ca377e.png)
【備忘録】カスタムAMI概要 + 構築手順

# AMI
**EC2の元になるイメージのこと**

### カスタムAMI
ソフトウェアをインストール・設定を変更した後の状態のインスタンスのイメージのこと

用途
- **カスタムAMI**からインスタンス作って**冗長構成**にする
- **障害発生時**に**カスタムAMI**からインスタンスを作って復旧する

## EC2→カスタムAMI・カスタムAMI→EC2
**1.AMIを取得
2.AMIからEC2インスタンスを作成**

**1-1.対象のインスタンスのアクション→イメージとテンプレート→イメージを作成をクリックする**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/332af7ad-c1a3-486f-a1c7-7105e1b457ba.png)

**1-2.イメージ名を付けてイメージを作成をクリックする**
![image 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/d1556c16-ebbe-4183-894d-2077bf9cf0d9.png)

**1-3.AMI現在作成中という表記が出ればOK**
![image 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/d4585ff5-f5f6-4855-bbd8-91651bd91ae8.png)

**2-1.AMIを選択して、AMIからインスタンスを起動をクリックする**
![image 3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/b04b1d73-c48a-4426-bd02-384941e02611.png)
【備忘録】AWS踏み台サーバ概要 + 構築手順

# 踏み台サーバー概要
**privateサブネットにあるサーバにログインするために使うサーバのこと**

**メリット:基本EC2インスタンスを止めてるので料金がかからない
SSH出来るサーバを基本止めてるのでＷebサーバが安全
デメリット:管理するサーバが１台増える**

# 踏み台サーバーアーキテクチャ
**1.Webサーバーは常にレスポンスを返さなければならないのでpublicサブネットに
配置する必要がある
そうすると、WebサーバのインスタンスのSSHの口が開きっぱなしになるため危険**

**2.Webサーバのインスタンスはprivateサブネットに置いて、webサーバに対してSSHするための踏み台サーバをpublicサブネットに置く + 踏み台サーバはSSHしたいタイミングのみ起動する**

**3.WebサーバへのHTTPアクセスはLBを配置して行う**

## 踏み台サーバ構築手順
**1.EIPの取得
2.踏み台用EC2の構築
3.WebサーバのEC2インスタンスのセキュリティグループを変更**

**3-1.SSHのソースを踏み台サーバが持つセキュリティーグループに変更する
インバウンドルールにセキュリティグループを指定すると、そのセキュリティグループに対応したプライベートIPアドレスからのアクセスを許可するという意味になる**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/1e3f052f-436b-45c1-bd37-67d2957ba276.png)


**3-2.踏み台サーバからWebサーバへアクセスするにはポートフォワーディングを行う
もしくは踏み台サーバからWebサーバへ直接SSHする
3-3.踏み台サーバに入る**
![image 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/8ba47739-67a3-498e-84ca-7f2aee5c9878.png)

**3-4.Tera Termの設定→SSH転送→追加をクリックし、ポートに10022・リモート側ホストにWebサーバのプライベートIP・ポートに22を入力する**
![image 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/4943404f-cb27-41dd-9148-9f87537ae291.png)

**3-5.新しいTera Termを起動して、ホストにlocalhost・TCPポートに10022を入力する**
![image 3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/5794fc6b-5861-4466-92c1-f501488b9550.png)

**3-6.ポートフォワードによってWebサーバに入れる**
![image 4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/224602b6-83a2-4926-836b-fae8e3886ec6.png)
sqlcl で Excelファイルをデータベース表へロードしてみた (2025/02/17)

# はじめに

sqlcl 24.4.1 でLoadコマンドがExcelファイルに対応しました。
「Load command modified to support loading data from Excel」
ExcelファイルをOracle Databaseにロードするのにsqlclを使ってみました。

# 事前準備

- sqlcl 24.4.1 のダウンロードと解凍
- Java 11 or 17 or 21 のインストール

# Excelファイルのロード

### 表作成DDLの確認
コマンドリファレンス：load <表名> <ファイル名> show

```sql
$ ./sql iris/<password>@pdb


SQLcl: Release 24.4 Production on Mon Feb 17 05:06:25 2025

Copyright (c) 1982, 2025, Oracle.  All rights reserved.

Connected to:
Oracle Database 23ai EE Extreme Perf Release 23.0.0.0.0 - for Oracle Cloud and Engineered Systems
Version 23.7.0.25.01
SQL> load tn17 tn17.xlsx show
The provided File extension does not match set loadformat parameter
SQL> set loadformat xlsx
SQL> load tn17 tn17.xlsx show
```

```sql
Show DDL for table IRIS.TN17


CREATE TABLE IRIS.TN17
 (
  年度 VARCHAR2(26),
  FISCAL_YEAR VARCHAR2(26),
  系統 VARCHAR2(26),
  駅 VARCHAR2(26),
  乗車人員総数 VARCHAR2(26),
  乗車人員定期 VARCHAR2(26),
  乗車人員普通 VARCHAR2(26)
 )
;

SUCCESS: Processed without errors
```

1行目を列名としてDDLを生成しています。
カラム長は実データの長さが反映されていませんので、修正が必要のようです。

### データのロード
上述のDDLを参考に、事前にロード先として作成した表(tn17)にロードしてみます。


```sql
SQL> load tn17 tn17.xlsx

Load data into table IRIS.TN17

#ERROR Insert failed for row  1
#ERROR 駅: Unable to format column
#ERROR Row 1 data follows:
平成25,2013,総数,,3317344,1962690,1354654
#ERROR Insert failed for row  156
#ERROR 駅: Unable to format column
#ERROR Row 156 data follows:
平成29,2017,京葉線,,52770,31731,21038
#INFO Number of rows processed: 161
#INFO Number of rows in error: 2
#INFO Last row processed in final committed batch: 161
WARNING: Processed with errors
```

いくつかの行でエラーがありましたが、ロードができました。

# そのほかのオプション

sqlcl で Excelファイルから表を作成するオプション
- CREATE / CREATE_DDL

```sql
load tn17 tn17.xlsx create_ddl


Create new table IRIS.TN17
CREATE TABLE IRIS.TN17
 (
  年度 VARCHAR2(26),
  FISCAL_YEAR VARCHAR2(26),
  系統 VARCHAR2(26),
  駅 VARCHAR2(26),
  乗車人員総数 VARCHAR2(26),
  乗車人員定期 VARCHAR2(26),
  乗車人員普通 VARCHAR2(26)
 )
;

#INFO Table created
SUCCESS: Processed without errors
```


sqlcl で 新規表を作成してロード

```sql
SQL> load tn18 tn17.xlsx new

Create new table and load data into table IRIS.TN17


CREATE TABLE IRIS.TN17
 (
  年度 VARCHAR2(26),
  FISCAL_YEAR VARCHAR2(26),
  系統 VARCHAR2(26),
  LINE VARCHAR2(26),
  駅 VARCHAR2(26),
  STATION VARCHAR2(26),
  マーク VARCHAR2(26),
  乗車人員総数 VARCHAR2(26),
  乗車人員定期 VARCHAR2(26),
  乗車人員普通 VARCHAR2(26)
 )
;

#INFO Table created
#ERROR Insert failed for row  1
#ERROR 駅: Unable to format column STATION: Unable to format column マーク: Unable to format column
#ERROR Row 1 data follows:
平成25,2013,総数,Total,,,,3317344,1962690,1354654
#INFO Number of rows processed: 161
#INFO Number of rows in error: 1
#INFO Last row processed in final committed batch: 161
WARNING: Processed with errors
```


# おわりに

sqlcl を使ってExcelの表からDDL作成やデータのロードができました。
制約事項などは下記参考情報を参照ください。

# 参考情報
- [Oracle SQLcl 24.4.1リリースノード](https://www.oracle.com/tools/sqlcl/sqlcl-relnotes-24.4.1.html)
- [Loading a File ](https://docs.oracle.com/en/database/oracle/sql-developer-command-line/24.4/sqcug/loading-file.html#GUID-374BF2F9-6F07-450A-BE76-0526FFC6DDF9)
【ショートカットキー　全ソフトウェア、VScode、コマンドライン】

## 全ソフトウェア
・ctrl　+　N➡新規ファイル
・ctrl　+　S➡保存
・ctrl　+　shift　+　S➡名前を付けて保存
・ctrl　+　o➡ファイルを開く
・ctrl　+　shift　+　N➡新規ウインドウ
・alt + Tab➡アプリケーション切り替え
・alt + F4➡アプリケーションを閉じる
・windowキー + space➡言語入力の切り替え
・home➡行の先頭に移動
・end➡行の後尾に移動
・pg up➡ページの最前列に移動
・ctrl + ←➡単語の先頭へ移動（単語の区切りの部分に移動ができる）
・shift + ↑/→/↓/←➡選択
・shift + home or shift + end➡行を選択
・ctrl　+　shift + Z➡１つ後の状態に戻す
・esc➡キャンセル
・Fn + F2➡ファイル名変更
・Tab➡フォーカス
・space➡チェック
・Tab + shift➡フォーカス戻る
・ctrl + J➡ダウンロードページを開く
・ctrl + H➡履歴ページを開く
・ctrl + T➡新規タブ
・ctrl + W➡タブを閉じる
・ctrl + tab➡タブの切り替え（進む）
・ctrl + shift + tab➡タブの切り替え（戻る）
・Ctrl + F5➡スーパーリロード
・ctrl + P➡プリントアウト
・alt + space→N➡ウインドウを最小化
・alt space→X➡ウインドウを最大化
・windowsキー　+ shift + S➡スクリーンショット

## VScode

・Tab➡インデント
・Tab + shift➡インデントを戻す
・ctrl + /➡コメントアウト
・alt + クリック➡複数選択
・ctrl + D➡同じ単語を複数選択
・ctrl + K➡複数選択スキップ
・ctrl + B➡サイドバーの切り替え
・ctrl + P➡クイックオープン
・ctrl + shift + P➡コマンドパレットを開く
・ctrl + F➡ファイル内検索
・shift + alt + F➡フォーマット整形
・ctrl + J➡コマンドライン
・ctrl + ファイル名➡ファイルを別タブで開く

## コマンドライン

・↑↓➡過去のコマンドを呼び出し
・ctrl + A➡先頭に移動
・ctrl + E➡末尾に移動
・ctrl + U➡行を削除
・alt + F7➡ログのクリア
・ctrl + shift + Enter➡管理者権限
【備忘録】AWS EC2・EBS概要 + 構築手順

# EC2概要
**AWS上に仮想サーバを建てるサービス**

### AMI
EC2インスタンス**の元になる**イメージ

### インスタンスタイプ
仮想サーバーの**スペック**を指定できる

### IPアドレス
- プライベートIPアドレス → サブネット内のIPが勝手に固定で割り当てられる
- パブリックIPアドレス → 可変グローバルIPを任意で割り当てられる.無料
- ElasticIPアドレス → 固定グローバルIPを任意で割り当てられる.有料

### セキュリティグループ
AWSリソースの仮想ファイルウォールのこと

### キーペア
**公開鍵**と**秘密鍵**の**ペア**

## EBS
**EC2のデータを保存出来るブロックストレージ
ネットワーク経由でアクセスしているので、デタッチ可能・同じAZのEC2にしかアタッチできない**

## EC2構築手順
**1.キーペアを作成
2.Elastic IPを取得
3.EC2インスタンスを構築**

**1-1.キーペア名・キーペアのタイプを指定してキーペアを作成する**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/917749a0-988b-4ae4-886d-a4dfe809f133.png)

**1-2.キーペアが正常に作成されましたと表示されればOK**
![image 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/585dc58a-ebc2-47c6-ab5f-8bd96730f97d.png)

**2-1.EIPのタグを指定する(そのまま名前になって使いやすい)**
![image 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/58165254-610c-4492-84d0-1f80594ee2c8.png)

**2-2.EIPが正常に割り振られましたと表示されればOK**
![image 3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/64d75002-e43e-41a1-9677-b05a9bb18ebb.png)

**3-1.インスタンス名・AMI・インスタンスタイプ・キーペア・ネットワーク設定(どのVPCのどのサブネットに属すのか・どのリクエストを通すのかを指定する)・EBSをそれぞれ指定する**
![image 4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/36c90c98-6112-4ed7-888d-e727d796c777.png)

**3-2.ステータスチェックが通っていればOK**
![image 5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/66b9daad-6e52-4dd6-9bd5-e0f07be8bea8.png)

**3-3.EIPを関連付けるをクリックする**
![image 6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/8c080ef7-9560-43b9-abf3-98171d4c90f5.png)

**3-4.EIPを関連付けるインスタンス・プライベートIPアドレスを指定する**
![image 7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/136d013b-d6ef-4b2a-bc89-4d35f9538dbe.png)

**3-5.teratermのIPにEIPを指定して接続する**
![image 8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/70ddf3cc-f40a-4c0e-b7fa-4a77a34d83d2.png)
CloudFront + S3のベストプラクティス：OAIを活用したセキュアなアクセス管理を体系的にまとめてみた

## はじめに
Amazon CloudFrontのOrigin Access Identity（OAI）は、CloudFrontがS3バケットのオリジンにアクセスする際に使用する特別なIDです。

OAIを利用することで、S3バケットへの直接アクセスを制限し、CloudFront経由でのみコンテンツを配信できるようになります。

## 書こうと思ったきっかけ
AWSのセキュリティ強化の方法を学んでいる中で、CloudFrontのOAIがS3バケットのアクセス管理に役立つことを知りました。

:::note note
**また、OAIを適切に設定することで、コスト削減やアクセス制御の簡素化が可能になる点にも興味を持ちました。**
:::

特に、誤った設定がセキュリティリスクを生む可能性があるため、正しい使い方を整理したいと思いました。そこで、OAIの概要や設定方法についてまとめることにしました。

## CDN（Content Delivery Network）とは？

CDN（Content Delivery Network）は、インターネット上でコンテンツ（画像、動画、CSS、JavaScript など）を高速かつ効率的に配信するための分散型ネットワークのことです。

https://qiita.com/free-honda/items/2b1895e9b676cbc53748

## CDNの仕組み
CDNは、世界各地に設置されたサーバー（エッジサーバー）を活用し、ユーザーの近くにあるサーバーからコンテンツを配信することで、以下のようなメリットを提供します。

### 1. 表示速度の向上
ユーザーの近くのサーバーからデータを取得するため、レイテンシ（遅延）が少なくなり、Webページの読み込み速度が向上します。

### 2. サーバー負荷の軽減
CDNがコンテンツをキャッシュすることで、オリジンサーバー（元のサーバー）へのアクセスを減らし、負荷を分散できます。これにより、大量のアクセスが発生してもサーバーが安定して動作します。

### 3. 可用性の向上
CDNは複数のサーバーにコンテンツを分散しているため、特定のサーバーがダウンしても他のエッジサーバーが代わりにコンテンツを提供できます。これにより、Webサイトの稼働率が向上します。

### 4. セキュリティの強化
CDNは、DDoS攻撃対策や不正アクセス防止の機能を備えている場合が多く、Webサイトの安全性向上にも役立ちます。

## OAIのメリット
- **セキュリティの強化**：S3バケットのパブリックアクセスを無効化し、CloudFront経由でのみアクセスを許可できる。
- **コスト削減**：S3からの直接アクセスを防ぐことで、CloudFrontのキャッシュを活用し、データ転送コストを削減。
- **アクセス制御の簡素化**：IAMポリシーを使用せず、CloudFrontのOAIをS3のバケットポリシーで管理可能。

## OAIの設定手順
### OAIの作成
- AWSマネジメントコンソールでCloudFrontに移動。
- 新しいディストリビューションを作成、または既存のディストリビューションを選択。
- オリジン設定で、オリジンタイプをS3バケットに設定。
- **Origin Access**の設定で**Restrict Bucket Access**を有効にし、**Create a New Identity**を選択。
- OAIの名前を入力し、**Create** をクリック。
- 「Yes, Update the Bucket Policy」を選択して、S3バケットポリシーを自動更新。

### S3バケットポリシーの設定（手動設定の場合）
OAIを手動で設定する場合、S3バケットのポリシーを以下のように変更します。
```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity OAI-ID"
      },
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::your-bucket-name/*"
    }
  ]
}
```
`OAI-ID` の部分には、作成したOAIのIDを入力します。

## OAIを利用する際の注意点
- OAIを使用すると、S3バケットへのパブリックアクセスはブロックされるため、S3のURLを直接使用できなくなる。
- CloudFrontディストリビューションの更新には時間がかかる場合がある。
- OAIを削除すると、CloudFront経由でのアクセスが失敗するため、事前にバケットポリシーを調整する。

## まとめ
CloudFrontのOAIを利用することで、S3バケットのセキュリティを強化しながら、効率的なコンテンツ配信が可能になります。

適切な設定とポリシー管理を行うことで、安全でコスト効率の高いデリバリを実現できます。
【デプロイ手法】ブルーグリーンデプロイってなんだ？

### ブルーグリーンデプロイとは
![スクリーンショット 2025-02-17 144702.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3575047/875450e5-cdaf-4cb3-9545-802bb246968d.png)
現在の本番環境（ブルー）とは別に新しい本番環境（グリーン）を構築した↑で、ロードバランサーの接続先を切り替えるなどして新しい本番環境をリリースする運用方法のこと。

面白いのが、別の新しい本番環境（グリーン）に何らかの追加仕様を施してきちんとwebサービスが運用出来ているのかを確認する。現在の本番環境を飽くまでもかえないのがミソ。

そして、大丈夫だと確認したら古い環境を消してしまう。

界隈では、Red/Blackデプロイとも言うらしいがほぼ同義として考えていいそう。

### 間違えやすい単語

・カナリアリリース
→少数のユーザーやサーバーに新バージョンを段階的に展開し、問題なければ全体に拡大する手法。
全体の環境を一括で切り替えずに徐々に以降する点がブルーグリーンデプロイと異なる。

・ローリングデプロイ
→サーバー群を複数のバッチに分け、順次新バージョンに更新する手法。更新中は古いバージョンと新しいバージョンが混在するのでユーザーが戸惑うこともある。

・イミュータブルデプロイ
→既存のサーバーを更新せずに新しい環境を作成して切り替える。ブルーグリーンデプロイと似ているが、切り替える後に旧環境を削除する点で異なる。（名前の通り飽くまでも不変なので）


### 参考文献（参照日2025年2月17日）

https://xtech.nikkei.com/atcl/nxt/keyword/18/00002/070800077/

https://circleci.com/ja/blog/canary-vs-blue-green-downtime/

https://garafu.blogspot.com/2018/11/release-strategy.html

https://dev.classmethod.jp/articles/elastic-beanstalk-deploy-policy/
【備忘録】AWS VPC概要 + 構築手順

# VPC概要
AWS上の仮想ネットワークで、VPC内にAWSリソースを作成できる
VPCのIPアドレスは/16・プライベートIPアドレスが推奨される

### サブネット
VPC内を区切るネットワーク
サブネット内にAWSリソースを作成出来る
サブネットはAZを指定して作成する

### インターネットゲートウェイ
VPC・インターネット間を通信出来るようにする機能

### ルートテーブル
サブネット毎に通信経路を決定する機能
VPCの外に出るときに何に飛ばしたいのかを指定する機能
IGW宛のルーティングが存在すると**パブリックサブネット**となる。
IGW宛のルーティングが存在しない場合は、**プライベートサブネット**となる。

### セキュリティグループ

**AWSリソース**の仮想ファイアウォール
IN/OUTをホワイトリストで設定(IP・ポート・プロトコル)
**ステートフル**なので、リクエストが許可されていれば、レスポンスを明示的に許可していなくても正しく返される

### ネットワークACL
**サブネット**の仮想ファイアウォール
許可拒否をIN/OUTで設定する
**ステートレス**なので、リクエストを許可すると、レスポンスも明示的に許可しなければ応答が送られない
サブネットを新規作成すると全通信が許可されたネットワークACLがサブネットにアタッチされる

## VPC構築手順
**1.VPCを作成する**
**2.サブネットを作成する**
**3.IGWを作成・アタッチする**
**4.パブリックサブネットのルートテーブルを作成・アタッチする**

**1-1.VPCを作成をクリック
1-2.IPv4CIDRブロックにプライベートIPを与える**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/293ea9fc-478e-4c37-912f-314c92fb966b.png)

**2-1.サブネットを作成をクリック
2-2.サブネットを作りたいVPCを選択する
2-3.サブネット名・AZを指定・サブネットのCIDRブロックを指定する**
![image 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/b7be25cf-3376-47c1-b2fe-7569e83ade5c.png)

**2-4.サブネットが正常に作成されましたと表示されればOK**
![image 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/28cf263c-d35a-43ff-bc99-7691b013dc2d.png)


**3-1.インターネットゲートウェイを作成をクリック**
**3-2.IGW名を指定する**
![image 3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/0498c376-7063-4cc9-b593-7cd5c22e9f6b.png)

**3-3.IGWが作成されましたと表示されればOK**
![image 4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/4ed0bd4d-6123-462c-ae13-d12e6767b443.png)

**3-4.IGWをアタッチしたいVPCを選択する**
![image 5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/40164460-9aef-45e5-a514-5c469f6bfc05.png)

**3-5.IGWが正常にVPCにアタッチされましたと表示されればOK**
![image 6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/21d8427b-b740-4df4-89ba-8037adbaa895.png)


**4-1.ルートテーブルの作成をクリック
4-2.ルートテーブルを適用するVPCを選択する**
![image 7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/46adab0f-ed15-42a0-a6f1-38acb3b1bf76.png)

**4-3.ルートテーブルが正常に作成されましたと表示されればOK**
![image 8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/10626ef3-e6ef-49ac-84dc-5360a9cf4dae.png)

**4-4.任意のルートテーブルを選択して、ルート → ルートを編集**をクリックする
![image 9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/a651660d-9e8c-4b0a-b0a4-b96f4a5c6b43.png)

**4-5.任意のルーティングを行う**
![image 10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/71ecbdfb-e11d-488f-9052-7ad36568bd3e.png)

**4-6.サブネットの関連付けを編集をクリックする**
![image 11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/42ca0753-30d0-417b-8d22-acb9b60a06f2.png)

**4-7.任意のサブネットにルートテーブルを紐づける**
![image 12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/df3c4ea8-859f-4906-a8e2-4287f14fdca2.png)
Node.js で import の順序が気になった話

# Node.js 22 で気になる挙動があったのでメモしておく

まとめ

- 静的な順序だった雰囲気だったけど，実行時間が反映されるようになった雰囲気がある
    - 単純な実行時間じゃなくて，非同期になった．というか

## Node 20 / 22 で import をしてみる

```
$ for s in node20 node22; do \
  echo "-- $s -- "; \
  for i in `seq 1 10`; do \
    docker compose run -v $(PWD):/app -w /app --rm $s test.js; \
  done; \
done
-- node20 -- 
[ 'a', 'b' ]
[ 'a', 'b' ]
[ 'a', 'b' ]
[ 'a', 'b' ]
[ 'a', 'b' ]
[ 'a', 'b' ]
[ 'a', 'b' ]
[ 'a', 'b' ]
[ 'a', 'b' ]
[ 'a', 'b' ]
-- node22 -- 
[ 'b', 'a' ]  # <= ここ
[ 'a', 'b' ]
[ 'a', 'b' ]
[ 'a', 'b' ]
[ 'a', 'b' ]
[ 'a', 'b' ]
[ 'a', 'b' ]
[ 'a', 'b' ]
[ 'b', 'a' ] # <= こk
[ 'a', 'b' ]
```

## 付録

<details><summary>details</summary>

```compose.yml
services:
  node20:
    image: node:20
    command: -v
  node22:
    image: node:22
    command: -v
```

```test.js
const results = []
const f = async () => {
  await Promise.all(['a', 'b'].map(async (i) => {
    await import(`./${i}.js`)
    results.push(i)
    return
  }))
  return
}
f().then(() => {
  console.log(results)
})
```

```
$ wc a.js b.js
       0       0       0 a.js
       0       0       0 b.js
       0       0       0 total
```

</details>

## Refs

 https://qiita.com/suin/items/a106289e2d1d8d9c1490
【PHP】header('Content-Type: application/json');の重要性

# `header('Content-Type: application/json');` の重要性

Web開発でAPIを作成する際、PHPの `header('Content-Type: application/json');` を適切に設定することは非常に重要。この設定をしないと、クライアント側のJavaScript（特に `$.ajax()` や `fetch()` などのAPI呼び出し）が正しく動作しない場合がある。

## サンプルコード
```sample.php
session_start();
header('Content-Type: application/json');

if (empty($_POST['id']) || empty($_POST['password'])) {
    echo json_encode(["success" => false, "message" => "IDとパスワードを入力してください"]);
    exit;
}

//仮の認証処理
if ($_POST['id'] === 'admin' && $_POST['password'] === 'pass') {
    echo json_encode(["success" => true]);
} else {
    echo json_encode(["success" => false, "message" => "認証に失敗しました"]);
}
//ほかの処理
//......
```

```sample.js
$(document).ready(function(){
    $("#login-form").submit(function(event){
        event.preventDefault();

        let id = $("#id").val();
        let password = $("#password").val();

        $.ajax({
            url: "sample.php",
            type: "POST",
            data: { id: id, password: password },
            dataType: "json",
            success: function(response) {
                if (response.success) {
                    window.location.href = "settings.php";
                } else {
                    $("#error").text(response.message);
                }
            },
            error: function(xhr, status, error) {
                console.log("AJAXエラー: ", xhr, status, error);
                $("#error").text("通信エラーが発生しました");
            }
        });
    });
});
```

## `header('Content-Type: application/json');` が必要な理由
1. **クライアント側が適切にレスポンスを処理できるようになる**
   - `$.ajax()` の `dataType: "json"` を設定している場合、レスポンスの `Content-Type` が `application/json` でないと、エラーになったり文字列として処理されたりする

2. **セキュリティの向上**
   - ブラウザがレスポンスの内容を適切に解釈することで、不必要なコンテンツスニッフィング（Content Sniffing）が防げる
   - `Content-Type` を明示しないと、ブラウザが勝手にレスポンスを解釈し、意図しない挙動を引き起こす可能性がある

## `header()` を忘れた場合の問題点
- レスポンスが `text/html` や `text/plain` として扱われ、JSONとしてパースされない
- `$.ajax()` の `success` コールバックで `response.success` にアクセスしようとしても `undefined` になる
- デバッグがしづらくなり、エラー処理が煩雑になる
マイナポータルでELP101エラーを解消するまでの道のり

## はじめに
先日住所変更申請を行うために市役所へ訪問しました。転出届手続きを未実施だったのですが、マイナポータルで手続きが出来ると担当者に教えて頂きました。しかしELP101エラーが出てしまい危うく頓挫するところでした。ヘルプデスクの人にも対応して頂き解決することができました。その時の内容を整理してみました。

## 概要
携帯の内容は以下です。
- iPhone15
- IOS18.3

エラー内容は以下です。
- マイナポータルに登録はできており、マイナンバーカードの情報を読み込む際にsafariのページへ遷移したら、プライペートモードになってしまい、ELP101エラーが発生。

## エラーへの対応 
ヘルプデスクの人にも助けて頂きながら、対応した内容が下記になります。
ちなみにヘルプデスクの番号は**0120-950-178→ガイダンス4→1**になります。

**実施項目①：アプリ→Safari→プライベートブラウザでも使用をOFF**
**結果：解決せず**

下記の実施項目②〜④をまとめて実行し、アプリの再インスールおよび、携帯の再起動を行ない解決
**実施項目②：Safariのアプリ→タブグループをスタートページに変更**
**実施項目③：アプリ→Safari→詳細→すべてのCookieをブロックをオフ**
**実施項目④：アプリ→Safari→履歴とWebサイトデータを消去で履歴を消去**

※ブラウザをChromeに変更してトライしたのですが、解決しなかったため、Safariでの解決策を模索しました。

## 考察
おそらく実施項目①が解決の鍵になっていたと思いますが、実施項目②と④および、アプリ再インストール、携帯の再起動で設定が更新されたのだと考察。

## 感想
マイナポータルを使用すれば、簡単に転出届の手続きができるため便利であると感じました。しかし、携帯のアプリに苦手意識がある人にとっては今回のエラーなどが、壁になりそうだと感じました。少しでも参考になればという意識と、自分の備忘録として記載しようと思い記事を書きました。


最後までご覧いただき本当にありがとうございました！！
vbsの作法 その96

# 概要
vbsの作法、調べてみた。
mailを送信してみた。

# 環境
windows11
outlook2007

# サンプルコード

```
Set olkApp = CreateObject("Outlook.Application")
Set objMsg = olkApp.CreateItem(0)
objMsg.bodyformat = 1
objMsg.To = "***@**.jp"
objMsg.Subject = "test"
objMsg.Body = "こんにちは。テストです。よろしく。"
objMsg.Send
msgbox "ok"

```

以上。
【SQL Developer】IOエラー:The Network Adapter could not establish the connection ベンダーコード17002が発生した際の解消方法

# 概要
SQL Developerを起動して、データベースにアクセスしようとしすると「IOエラー:The Network Adapter could not establish the connection ベンダーコード17002」が発生して接続できない場合の解消方法をまとめました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3533049/f30db7cb-b6c0-411a-acaf-4076b693e511.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3533049/e23a3fc9-696d-42d3-bcd4-8d37e3da26d7.png)

# 方法
Oracle関連のサービスが停止している可能性があるので、Oracle関連のサービスを手動で開始させて、再度データベースに接続します。

1. `Windowsキー` + `R`を押下し、「ファイル名を指定して実行」ウィンドウを表示する
1. `services.msc`と入力して「OK」ボタンを押下し、「サービス」ウィンドウを表示する
1. 「Oracle～」という名前のサービスを全てを対象に、右クリックし「開始」を押下
1. 再度SQL Developerからデータベースに接続を試みる

私は上記の方法で解消しました。

:::note
(4) を実施後に別のエラーメッセージが表示される場合は、SQL Developerを再起動して試してみてください。
:::

# 終わりに
昨日までは普通にデータベースに接続できていたのに翌日になると急に接続できなくなる時があるので、そういう場合は上記の手順で解消しています。

# 参考
[SQL Developer エラー「IOエラー The Network Adapter could not establish the connection 」が発生した場合の対処法](https://mebee.info/2022/12/06/post-87684/)
【フリーランスエンジニアが年収を倍にするための営業・交渉戦略】

# フリーランスエンジニアが年収を倍にするための営業・交渉戦略

## 🔥 はじめに
フリーランスエンジニアの成功は「技術力」ではなく、「営業力」と「交渉力」で決まる。
本記事では、以下のポイントを解説する。

✅ 1. フリーランスは技術よりも営業力が大事
✅ 2. 高単価案件を取る交渉術
✅ 3. 「学習 × 発信 × 実績」で案件を自動化

## ✅ 1. 営業力を鍛える方法
### 🔹 ポートフォリオを「技術紹介」から「課題解決型」に変える
- クライアントが「この人に頼みたい」と思う構成を意識する
- GitHubや技術ブログを「課題解決の証拠」として活用する

### 🔹 SNS・直営業・エージェントの活用
- Twitter・LinkedInで「価値提供の発信」を継続する
- 企業へ直接提案する（DMや問い合わせフォームを活用）
- フリーランス向けエージェントを適切に使う

## ✅ 2. 高単価案件の交渉術
### 🔹 交渉時に使うべき言葉
❌ 「もう少し単価を上げられませんか？」
✅ 「この施策を導入すれば、◯%のコスト削減が可能です。そのため、この単価が妥当です。」

### 🔹 クライアントの利益を最大化する提案
- クライアントが求める「成果」にフォーカスする
- 「価格交渉」ではなく「価値交渉」を意識する

## ✅ 3. 案件を「自動化」する戦略
### 🔹 学習 × 発信 × 実績
- スキルを学んだら「Twitter・Qiita・Note」で発信
- 実績が増えるほど「紹介案件」が増え、営業が不要になる
- このサイクルを回すことで案件獲得が加速する

## ✅ まとめ
フリーランスエンジニアが成功するには、「技術 × 営業 × 交渉」の3つが鍵。
本記事の戦略を活用し、年収を倍にしよう！
AWS Health管理通知の設定方法と注意点

# 内容
AWSを運用していると、メンテナンス通知等がAWSから届くことがあると思います。通常、下記の様なメンテナス等を含めた通知はAWSアカウント内に登録した主要連絡先メールアドレス（ルートユーザのメールアドレス）や代替連絡先メールアドレスに送付されます。

![health01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/68bebabd-8d47-4fa0-8a62-279bb06cdfbc.png)

ただ、主要連絡先や代替連絡先以外のメールアドレスで通知を受信したいパターンもあると思います。そのような場合、AWS管理通知を有効化するこのによってメール通知先から主要連絡先、代替連絡先を削除したり、他の受信したいメールアドレスを追加することが可能となります。

https://aws.amazon.com/jp/about-aws/whats-new/2025/01/general-availability-aws-managed-notifications/


# 手順
「AWS User Notifications」→「AWS マネージド通知サブスクリプション」に移動後、「AWS Health通知を有効にする」をクリックします。

![health02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/e4a471bd-8788-4b00-b47d-fcb448419118.png)

「サブスクリプション管理」をクリックします。下記はSecurityの例となりますが、デフォルトでは「主要連絡先」および「オペレーションの代替連絡先」、「セキュリティの代替連絡先」が設定されています。ここに配信チャネルを追加してメールアドレス等を設定することで任意の通知先を追加することが可能となります。

![health03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/9da3db24-753d-44f9-8c41-b3b1cb5b32ad.png)

# 注意点

下記にAWS管理通知を有効にした際、変更される内容について記載があります。

https://docs.aws.amazon.com/ja_jp/notifications/latest/userguide/managed-notifications.html

* メール通知元アドレスが変更される

下記の通り、メール通知元アドレスが変更されます。
変更前：no-reply-aws@amazon.com
変更後：health@aws.com

* メール形式が変更される

下記の様にメール形式が変更されます。

![health04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/42c0632e-e952-432f-821a-c1f66b27d1b6.png)
個人的備忘録：CORSを理解するために、Flask-CORSを使ってフロントエンドの通信テストをしてみた

## はじめに
Web開発をしていると、異なるオリジン（ドメインやポートが異なるサイト）からAPIを呼び出すことがあります。

:::note info
***しかし、ブラウザのセキュリティ機能により、CORS (Cross-Origin Resource Sharing) の設定がないとアクセスが制限されてしまいます。***
:::

この記事では、PythonのFlaskを使って簡単にCORSを有効にし、ブラウザからAPIを呼び出せるようにする方法を紹介します。

## 1. 必要なライブラリをインストール

まず、FlaskとFlask-CORSをインストールします。

```sh
pip install flask flask-cors
```

## 2. Flaskサーバーを作成

以下のコードで簡単なFlaskサーバーを作成します。このサーバーは、`/api/data` というエンドポイントを持ち、CORSを有効にしています。

```python
from flask import Flask, jsonify
from flask_cors import CORS

app = Flask(__name__)
CORS(app)  # すべてのオリジンからのリクエストを許可

@app.route('/api/data')
def get_data():
    return jsonify({"message": "Hello, CORS!"})

if __name__ == '__main__':
    app.run(debug=True, port=5000)
```

このコードを `app.py` というファイル名で保存します。

## 3. フロントエンドを作成

次に、CORSの動作を確認するための簡単なHTMLページを作成します。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CORS テスト</title>
</head>
<body>
    <h1>CORS テスト</h1>
    <button onclick="fetchData()">データ取得</button>
    <p id="result"></p>

    <script>
        function fetchData() {
            fetch('http://127.0.0.1:5000/api/data')
                .then(response => response.json())
                .then(data => {
                    document.getElementById('result').innerText = data.message;
                })
                .catch(error => console.error('Error:', error));
        }
    </script>
</body>
</html>
```

このHTMLファイルを `index.html` として保存します。

## 4. Flaskサーバーを起動

ターミナルでFlaskサーバーを起動します。

```sh
python app.py
```

## 5. 動作確認

1. `index.html` をブラウザで開きます。
2. 「データ取得」ボタンを押します。
3. `Hello, CORS!` のメッセージが表示されれば成功です。

**実際のブラウザ画面**

![Screenshot 2025-02-17 at 13.06.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/aea8095f-c5bb-41da-9c1b-6d1988e2ff76.png)

**Flaskサーバー画面**

![Screenshot 2025-02-17 at 13.07.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/a8dad1f7-fcdb-4b24-bf31-f36512a2fb5e.png)

## 6. CORSの制限をカスタマイズ

すべてのオリジンを許可するのではなく、特定のオリジンのみ許可することも可能です。

```python
CORS(app, resources={r"/api/*": {"origins": "http://example.com"}})
```

これにより、`http://example.com` からのリクエストのみ許可されます。

## まとめ

- Flask-CORSを使えば簡単にCORSを有効化できる。
- フロントエンドからAPIを呼び出してCORSを確認できる。
- CORSの設定をカスタマイズして、特定のオリジンのみ許可可能。

この方法を使えば、CORSに悩まされることなく開発を進められます。**ぜひ試してみてください！**
CHFIに合格したので、備忘録として残します

# はじめに
Computer Hacking Forensic Investigator（CHFI）試験に合格したので、備忘録として残します。

# Who am i ?
そこらへんにいる社内SEをしております。
趣味でデータの復元を行っている程度の人間です。
EC-Councilの資格はCHFIの他にCNDを取得しています。

# この記事の想定読者
CHFIに興味を持っているが、いまいち試験を受ける気になれない人
CHFIについて知りたい人
その他

# 背景
なぜCHFIを受験しようと思ったかというと、前職でCEHを持っている方がいて、その方にフォレンジック好きならこっち受けてみたらというアドバイス（？？）を受けて目指しました。
後は、まだ日本でメジャーではない資格を取っておいて、後からとる人にマウン（殴
そんな浅はかな理由は置いといて、体系的に学んでみたかったというところにありますね。
ハンズオン環境もあるので、SANSなどと同じように練習できると思ったからです。

後は日本のデジタルフォレンジック資格が単に見当たらなかったというのもあります。
日本にはデジタルフォレンジック研究会なるものがあります。
そこの資格CDFPシリーズですかねくらいしかなかったと思います。
ちなみにCDFPシリーズだと自分はBしかもっていません。
管理者資格はガチ目にやっている人にしか解けない問題ばかりで、いい試験だと思います。

https://digitalforensic.jp/

# 本題
CHFIについてですが、自分は以下から申し込みしました。
自分の場合だと、講義から受けましたが受験資格があればそのまま試験から受けれるみたいです。（そのあたりはよくわからないので、別途調べる必要あり）
https://www.gsx.co.jp/services/securitylearning/eccouncil/chfi.html

CHFIは主にデジタルフォレンジックで必要な知識を広く浅く（諸説あり）体系的に学べるものとなっていました。
かなりの量があり、試験の山を張るなんてできるもんならやってみろというくらいには量があります。
（テキスト資料重すぎて足の小指折れそう）

少し解せなかったのは、ベンダーフリーという名の研修ではありますが、バチバチにベンダーのツールが出てきます（まぁフォレンジックの形式上致し方ない）
それもあり、さらにどこを勉強したらいいかわからなくなったりします。

後は細かい法律がぽこぽこと出てくるので、法律についての知識も必要となってきます。
日本の法律であれば、ある程度条文の解釈を行うものになると思いますが、米国の試験である以上、米国の法律となります。
それもこの試験の難しいところだと思います。

私はEC-Councilの資格はCHFIの他にCNDを取得していますが、CNDの後に受けるのが望ましいと思いました。

CEHを受けてから、受けてもいいのですが、根本がレッド寄りの知識によってしまう可能性があるので、CNDでブルーの知識が明確になっているうちに、CHFIを受けるのが吉だと思います。
同じブルーなので。

別に最初からCHFIを受けてしまっても構わんのだろ？（某赤服のアーチャー）
みたいな人はどうぞ。そのまま受けちゃってください。
受け終わった人にはこの言葉を捧げます。
「喜べ少年、君の願いはようやく叶う」

CNDについては正直合格体験記が上がりまくっているような気がするので、自分が改めてあげることはないかなぁ…。
どうしてもってお願いされたら出血大サービスで…etc

# 勉強方法
ざっと箇条書きで記載しておきます。

研修の受講
テキストの復習
ネットサーフィン

主にこの3つとなります。

CHFIの合格点については、特段ネット上には落ちていません。
けど確か受ける前にいくつかは書いてたような気がします。
それは自分で受けてみてのお楽しみにしといてください。（変動制を起用してたような気がするのでめったなことは言えない）

けどCHFIの研修で割と詳しくいろいろと教えてくれるので、聞き逃さないようにしたら大丈夫です。
（ん？研修が高すぎて受けれない？まぁ…確かに高いよね…大丈夫！分割払いで（殴）


# 試験当日
試験当日はパスポートか身分証として必要となります。
尚且つ日本の免許証を使う場合は、先にGSXの事務局に連絡しておかないといけないみたいです。
試験の担当官が米国の方なので、日本の免許になじみがないため、身分証として機能せずに試験日当日に試験が受けれないなんて不祥事がたまにあるみたいです。

試験時間は4時間あります。
体感的には2時間で解き、1時間で見直しというのが丸いと思います。
見直しは可能です。（CISSPなどみたいに見直しができないなんてことはない）

後は試験の担当官が米国の方なので、当然英語でしゃべってきますが、初めにチャットか通話かで選べます。
英語に自信がある方は通話を。
自身がない方はチャットを選んだらいいと思います。

チャットの場合は、翻訳サイトを通して会話をしていました。
まれに英語を日本語に直してくれる心優しき方もいます。

試験はかなり疲れました。（夜中0時から試験を始めた人）
そのまま眠るように布団に入りました。

ちなみに結果はすぐに出ます。（CISSPなどと同じ）

# 最後に
マークダウンなのに、彩がなくて悲しい？
確かに彩なくてすみません。
次は考えます。

とまぁフォレンジックを体系的に学びたいということであれば、この資格を取っても損はないと思います。

頑張って挑戦してみてください！！
AVHzY CT-3をレビュー

## はじめに
こんにちは、bockringです。現在、fx-CG50のレビュー記事の執筆とそのための検証を進めているのですが、中々に時間がかかるので一度箸休め的にレビューをしていこうと思います。

~~Luaスクリプトの紹介をするために少し勉強していたら全然箸休めにならなかったのは内緒。~~

ちなみに、今回はこの安い商品と比べたものの高い方を買った感じです。

https://amzn.to/41hmq5A

## AVHzY CT-3とは
AVHzY CT-3(以後`CT-3`と表記)は、YK-LAB Shizukuの外装カスタム品です。26V=6Aまで対応し、数値は6桁で表されます。そのため10V未満では0.01mV(10μV)で、10V以上でも0.1mVの精度で測定できます。電流についても0.01mA(10μA)の精度で測定可能です。

https://amzn.to/4k49cR6

また、液晶に128×160画素のカラー液晶を搭載しているので、機能も豊富です。日本語対応も1つの特徴と言えるでしょう。

電子負荷搭載モデルにするか迷いましたが、電子負荷は自作出来そうなので一旦パスとしました。

というか中華製の負荷装置を2つ持っています。1つは3.0~21.0V=0.00~3.50A(35W)のUSB電子負荷、もう1つは1.00~30.00V=0.00~9.99A(60W)の電子負荷です。USBテスターで20Vのトリガーを掛けた上で前者を1.75A、後者を3.00Aに設定して負荷試験を行うと合計4.75A、つまり95Wで、ほぼ100Wの負荷試験が可能です。

簡易オシロスコープ機能も搭載しているようですが、[以前組み立てたオシロスコープキット](https://qiita.com/bockring/items/7b989ad18243073d494c)より性能が良さそうです。(サンプリングレート約1.5倍)
→今度USB↔︎BNC-Jの変換アダプタを自作してオシロスコープ化しようと思います。(しっかり過電圧保護の回路も追加します)

そして外部電源/通信ポートを搭載します(何かと便利)。

## First Impression
まず最初にこれだけは言っておかないと気が済みません。**画面が見やすい**！そして、**日本語表示ありがたい**！多機能ではあるものの一応繋げば動く系のデバイスでもあるので、気軽に使えます。

しかし、操作に問題があります。全ての機能を1つの入力デバイスで実現しているため、操作性に難があります。また付属のクイックマニュアルには基本的な機能の説明のみ記載されているため、詳しい操作はWeb上で確認する必要があります。

というのもこの製品の入力デバイス(Alps製と謳われています)の入力操作は3種類で、右倒し・左倒し・押し込みだけなので、これに1回押し・2回連続押し・長押しの3種類を重ね、以下のような機能を持ちます(ホーム画面からの推移)
| クリック・倒し | クリック方法 | 機能 |
|:-|:-|:-|
| 押し込み | 1回 | 表示切り替え |
| 押し込み | 2回 | 電圧推移グラフ |
| 押し込み | 長押し | 設定 |
| 右倒し | 1回 | 電子負荷メニュー |
| 右倒し | 長押し | 時計 |
| 左倒し | 1回 | ツールメニュー |
| 左倒し | 長押し | 高度な機能のメニュー |

※メニュー名などは私が勝手に命名したものです。

また、メニュー画面や設定画面では、以下のようになります。
| クリック・倒し | クリック方法 | 機能 |
|:-|:-|:-|
| 押し込み | 1回 | 決定 |
| 押し込み | 2回 | 戻る |
| 右倒し | 1回 | 右/下の項目を選択•設定値の増加 |
| 右倒し | 長押し | 1回右倒しの連続操作 |
| 左倒し | 1回 | 左/上の項目の選択•設定値の減少 |
| 左倒し | 長押し | 1回左倒しの連続操作 |

この操作はわかりやすいですね。

とはいえ、1つの入力デバイスで最大7つの機能を割り当てています。そのせいで操作がかなり難しくなっています。

## 便利機能
このテスター、細かいところの芸が細かいのですが、1つが画面回転です。中にジャイロセンサーが組み込まれているようで、上下方向を自動的に切り替えてくれます。何気に便利です。

そして、この手のUSBテスターには搭載されている機能ですが、急速充電のトリガー機能は便利です。特に、PD PPS対応あるいはQC 3.0移行に対応のACアダプタを使えばかなり自由に電圧を変えられます。

私の例では、CIO SMARTCOBY Pro Slimにこのテスターを差し込み(USB-C)、以下のように操作します。
```
[←][↓][↓][→][→][↓][→][↓]
```

その後、`←`と`→`キーの操作で電圧を調整します。私の場合、`PPS 3.3-11V = 3A`までの対応なので、それ以上の電圧を求める場合は`12V = 2.92A`/`15V = 2.33A`/`20V = 1.75A`の3種類の固定電圧(Fixed)オプションを選択する必要があります。PPSでは20mVずつ(QC 3.0では200mVずつ)電圧を変更できるので、安定化電源の代わりになります。

5V/9V/12V/15V/20Vが使えればほとんどの物は動作すると思いますし、3.3Vが必要ならPPSを使えば対応できます。この広範囲な設定には若干の欠点があります。それは、**4V以下のトリガーをかけると落ちる**ことです。というのもテスターに外部電源を接続しないままだと、最低動作電圧の4Vを下回るため、電源が落ちます。

逆にその点だけ注意すれば、ある程度出力ができるType-AあるいはType-C端子を持つモバイルバッテリーを用いてどこでも電源が使えるわけです。非常に便利。

## PC接続
CT-3は製品上部のUSB Micro-B端子でPCと接続することが可能です。接続すると、保存容量が**ほぼ青天井**のなります。PC経由(オンライン)レコードでは20Sa/Sが上限のようで、オフラインレコードでは100Sa/Sまで可能なので、少し微妙には感じます。

ということで充電が死にかけのiPad(最大20W給電)への給電の様子です。
![20250209-1728_29cd9487823417eb78b89ce43461763f.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777721/ce018755-36a7-f795-5ccf-46ef96b1f62d.png)

なかなか見やすいグラフになっていると思います。(まぁ、なぜか32W給電の瞬間があるのは置いといて…) これはオフラインレコードしたものを読み込んでいます。しかし、拡張子が`.shizukuRecord`みたいな独自のもので、`.csv`で保存してくれよ〜とも思います。

## Luaスクリプトによる制御
**待っててくれ！**
curlコマンドのメモ

curlコマンドを使う中で自分が気になったことをメモ。

### ローカルサーバーに対してリクエストを投げるとエラーになる。
proxy環境下でブラウザからHTTPリクエストすると正常に通るのに、curlコマンドで実行するとエラーが発生する。
ブラウザではproxy設定をしているのでリクエストが通る。でもcurlコマンドのためだけにproxy関係の設定を変えるのは面倒。
#### `--noproxy`オプションを使い、proxyを使わずにリクエストする
```bash
# --noproxy [ドメイン]　を指定。
curl http://localhost:8080/books --noproxy localhost
```
個人的備忘録：Go × Echo で CORS を管理する middleware.CORSWithConfig を体系的にまとめてみた

## はじめに
`middleware.CORSWithConfig` は、Go の Echo フレームワークで CORS（Cross-Origin Resource Sharing）を設定するためのミドルウェアです。

CORS は異なるオリジン間でのリソース共有を制御するために使用され、適切に設定することで API のセキュリティと利便性を両立させることができます。

本記事では、`middleware.CORSWithConfig` の基本的な使い方や詳細な設定方法について解説します。

## CORS とは？
CORS（Cross-Origin Resource Sharing）は、異なるオリジン（プロトコル、ドメイン、ポートが異なるリソース間）の通信を許可または禁止する仕組みです。

例えば、`https://example.com` のフロントエンドが `https://api.example.com` の API を呼び出す場合、デフォルトではブラウザがクロスオリジンリクエストをブロックします。

CORS を適切に設定することで、これを許可することができます。

https://qiita.com/free-honda/items/52ba4aad28b6bf241a9b

https://qiita.com/free-honda/items/61f08f393fca64a5b47b

## middleware.CORSWithConfig の基本
Echo フレームワークでは、`middleware.CORS()` を使うことで簡単に CORS を有効にできます。しかし、より細かい設定が必要な場合は `middleware.CORSWithConfig` を使用します。

### インストール
まず、Echo フレームワークをインストールしておく必要があります。

```sh
go get -u github.com/labstack/echo/v4
```

### 基本的な実装例
`middleware.CORSWithConfig` を使用することで、許可するオリジンやメソッド、ヘッダーを細かく設定できます。

```go
package main

import (
	"github.com/labstack/echo/v4"
	"github.com/labstack/echo/v4/middleware"
)

func main() {
	e := echo.New()

	// CORS 設定
	e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
		AllowOrigins: []string{"https://example.com", "https://api.example.com"},
		AllowMethods: []string{echo.GET, echo.POST, echo.PUT, echo.DELETE},
		AllowHeaders: []string{"Content-Type", "Authorization"},
		AllowCredentials: true,
	}))

	// エンドポイント
	e.GET("/hello", func(c echo.Context) error {
		return c.String(200, "Hello, World!")
	})

	e.Start(":8080")
}
```

## middleware.CORSConfig の設定項目
`middleware.CORSConfig` には、さまざまな設定オプションがあり、必要に応じてカスタマイズできます。

| 設定項目         | 型               | 説明 |
|----------------|----------------|------------------------------------------------|
| `AllowOrigins` | `[]string`      | 許可するオリジンのリスト（`*` を指定するとすべて許可） |
| `AllowMethods` | `[]string`      | 許可する HTTP メソッド（`GET`, `POST` など） |
| `AllowHeaders` | `[]string`      | 許可するリクエストヘッダー |
| `ExposeHeaders` | `[]string`      | クライアントに公開するレスポンスヘッダー |
| `AllowCredentials` | `bool`       | 認証情報（クッキーなど）を許可するか |
| `MaxAge`       | `int`           | プリフライトリクエストのキャッシュ時間（秒単位） |

## まとめ
`middleware.CORSWithConfig` を使用することで、Echo フレームワークで詳細な CORS 設定が可能になります。

**基本的な設定に加え、セキュリティを考慮しつつ適切な設定を行うことが重要です。**

### **ポイントまとめ**
- `middleware.CORSWithConfig` を使うと詳細な CORS 設定が可能
- `AllowOrigins`, `AllowMethods`, `AllowHeaders` などの設定を適切に行う
- ローカル開発時と本番環境で異なる設定を適用する
- `AllowCredentials` を `true` にする場合はオリジンの設定に注意

CORS の適切な設定を行い、安全な API を構築しましょう！
【初心者向け】ディスク I/O の可視化（ビジュアライゼーション）【５分で読める】

# ディスク I/O の可視化（ビジュアライゼーション）

理解のために小咄形式でまとめました。

:::note info
システムパフォーマンス関連記事の目次
- [【初心者向け】システムパフォーマンス関連まとめ【それぞれ５分で読める】](https://qiita.com/nouernet/items/d3efe67e0f52a92e061d)
:::

**登場人物**
- **太郎（後輩）**：入社1年目の若手エンジニア。
- **花子（先輩）**：システムエンジニア歴3年の先輩。

**場面：オフィスのホワイトボード前**
*太郎がパフォーマンスデータを分析しながら、花子に質問する。*

**太郎**：「花子先輩、ディスク I/O のパフォーマンスデータを `iostat` や `sar` で取得したんですが、数値だけだといまいち `全体の傾向` がつかめません。どうすればいいでしょう？」

**花子**：「いい質問ね。 `ビジュアライゼーション（可視化）` を使うと、 `数値の羅列` では分かりにくい `異常や傾向` を一目で把握できるわ。」

---

### **可視化（ビジュアライゼーション）の解説**
**花子**：「ビジュアライゼーションには、 `データのパターンや異常を見つける` のに適したいくつかの種類があるの。特に `ディスク I/O の分析` では次の 5 つが役立つわ。」

1. **折れ線グラフ**
2. **レイテンシ散布図**
3. **レイテンシヒートマップ**
4. **オフセットヒートマップ**
5. **使用率ヒートマップ**

---

#### **1. 折れ線グラフ**
**花子**：「`折れ線グラフ` は `時間経過による変化` を見るのに適しているわ。」

- **IOPS（1秒間の I/O 数）** や **スループット（データ転送量）** を時間ごとにプロットする。
- システムの負荷の変化や、 `突発的なスパイク（急激な負荷増加）` を視覚化できる。

**太郎**：「ってことは、 `深夜に IOPS が急増している原因` を探るのに役立ちそうですね！」

---

#### **2. レイテンシ散布図**
**花子**：「`レイテンシ散布図` は、 `I/O の応答時間（レイテンシ）` の分布を見るのに便利よ。」

- **横軸**：時間
- **縦軸**：I/O のレイテンシ（ミリ秒単位）

「これをプロットすると、 `高レイテンシの I/O が特定の時間帯に集中しているか` や、 `外れ値（異常に遅い I/O）` がすぐ分かるわ。」

**太郎**：「なるほど、 `一部の I/O だけ異常に遅い` というケースを発見しやすくなるんですね！」

---

#### **3. レイテンシヒートマップ**
**花子**：「`レイテンシヒートマップ` は `長時間のデータ` を `一目で把握できる` のが特徴よ。」

- 色の `濃淡` で `レイテンシの大小` を表現する。
- 例えば、 `1日 24時間分のデータ` を `縦方向に時間、横方向にレイテンシ` として可視化する。

「これなら `特定の時間帯にだけ遅延が発生している` という `隠れたパターン` も見つけられるわ。」

**太郎**：「確かに `ヒートマップ` なら `全体の傾向` が一目で分かりますね！」

---

#### **4. オフセットヒートマップ**
**花子**：「`オフセットヒートマップ` は `ディスクのブロックごとのアクセスパターン` を可視化する手法よ。」

- **横軸**：ディスクのオフセット（ブロックアドレス）
- **縦軸**：時間
- **色**：アクセス頻度（濃いほど多い）

「これを使うと `特定の範囲だけが頻繁にアクセスされている` ことが分かるの。」

**太郎**：「例えば、 `データベースの特定のテーブルだけが集中的にアクセスされている` ことが可視化できるんですね！」

---

#### **5. 使用率ヒートマップ**
**花子**：「`使用率ヒートマップ` は `CPU や I/O デバイスの使用率の変化` を見るのに使うわ。」

- **横軸**：時間
- **縦軸**：デバイスや CPU コア
- **色**：使用率（赤＝高負荷、青＝低負荷）

「例えば `CPU の 1コアだけが異常に負荷が高い` 場合、それが `I/O のキュー待ちが原因か` を分析できるの。」

**太郎**：「たしかに `リソースの偏り` を見つけるのに役立ちそうですね！」

---

**花子**：「これらの `可視化手法` を `交通監視システム` に例えると分かりやすいわ。」

1. **折れ線グラフ → 高速道路の交通量の変化**  
   - `時間ごとにどれくらいの車が通ったか？`

2. **レイテンシ散布図 → 渋滞発生の場所と時間**  
   - `どの時間帯・場所で渋滞が発生しているか？`

3. **レイテンシヒートマップ → 都市全体の渋滞状況**  
   - `どのエリアが恒常的に混んでいるか？`

4. **オフセットヒートマップ → 駐車場の混雑状況**  
   - `特定の区画だけ満車になっている？`

5. **使用率ヒートマップ → 交差点ごとの混雑具合**  
   - `どの信号がボトルネックになっている？`

**太郎**：「なるほど！ `ビジュアライゼーション` は `データの渋滞解析` みたいなものなんですね！」

---

### **まとめ**
**花子**：「数値だけでは見えなかった `ボトルネックや異常なパターン` を発見するために、 `適切なビジュアライゼーション` を活用するのが重要よ。」

**太郎**：「ありがとうございます！ `Grafana` で `折れ線グラフ` と `ヒートマップ` を作って、 `ディスク I/O の傾向` を分析してみます！」

# 参考リンク

システムパフォーマンス関連記事の目次

- [【初心者向け】システムパフォーマンス関連まとめ【それぞれ５分で読める】](https://qiita.com/nouernet/items/d3efe67e0f52a92e061d)

システムパフォーマンス関連記事は、以下の書籍を参考に記述しています。

- [［改訂新版］プロのためのLinuxシステム構築・運用技術](https://www.amazon.co.jp/dp/B01LZURAPK)
- [改訂2版 ネットワークエンジニアの教科書](https://www.amazon.co.jp/dp/B07NXQ4TDV)
- [絵で見てわかるシステムパフォーマンスの仕組み](https://www.amazon.co.jp/dp/B00LHFOTF4)
- [詳解 システム・パフォーマンス 第2版](https://www.oreilly.co.jp/books/9784814400072/)
- [入門 モダンLinux](https://www.oreilly.co.jp/books/9784814400218/)
- [Linuxシステム管理](https://www.oreilly.co.jp/books/9784873113463/)
【4年目のエンジニアが成功失敗事例をYWTフレームワークで振り返る】

## はじめに
おつかれさまです〜！

フロントエンドとバックエンドのエンジニアをしております。佐々木です。

今回は、エンジニア4年目が終わりに近づいているので、4年間の成功失敗を振り返りたいとおもいます！

主に、失敗事例をどのように捉え、次に何をするのかを書いているので、FBがあれば是非いただけるとありがたいです〜🙏

## 成功 ≒ Y:やったこと
- 業務要件、システム要件定義の中で、資料を用いたお客様への改善提案ができるようになってきた。(現在進行形)
 - フロントとバックエンドそれぞれの要件からテストまで一人称で出来るようになった
 - Webサーバー、APサーバー構築ができるようになった

## 失敗 ≒ W: わかったこと
 - システムを作るだけでは、本質的なお客さんの課題解決にならないことを知った
 - 実装したコードの動作確認において、正常系（想定通りの動作）のみをチェックし、異常系（エラーケース）の確認を怠っていた
     - テスト実施者によって問題が発見され、後から修正作業が必要となり、結果的に余分な工数が発生してしまう
 - 設計の詳細が不十分なまま実装を始めてしまい、開発しながら設計を考えることになった結果、設計書の更新が後手に回ってしまった
    - 「とりあえず実装」をやめる
    -  設計者と実装者は基本セットが望ましいと知った
 - コードを書くスピードが遅い
 - 他の人に仕様に関して質問されると、コード見て調べればええやん...と思ってしまっていたこと
    - これが起因して、沢山質問を受けてしまい、1日の3分の2をMTGで失ってしまった

## 失敗(W:わかったこと)の背景、次にやること
- システムを作るだけでは、本質的なお客さんの課題解決にならないことを知った
     - 今まではエンド→ベンダー→弊社の立ち位置で仕事をしたり、弊社チームの中だけで仕事をすることが多かったので、指示されたシステムを作ることで評価いただいていた
     - 今はエンド→弊社という立ち位置(厳密には違うけど)で仕事をしているため、よりお客さんに近い立ち位置で仕事をすることが多くなっため、お客さんが抱えている課題の解決が評価に繋がることを知った
    - SES業界の中で、直エンドで仕事をいただけることは難しいと思うが、『エンドのお客様と利用者の課題解決』を軸にしてMTGの場で改善提案を実施することが大切だと知った。
 - 実装したコードの動作確認において、正常系（想定通りの動作）のみをチェックし、異常系（エラーケース）の確認を怠っていた。
    - 実装を作る工数と動作確認の工数を分けて考えることができておらず、実装を作る工数で上長に見積もりを出してしまっていたため、動作確認に十分な時間が取れなかった
    - 上長に適切な見積もりを出せるように、機能開発に必要な画面(コンポーネント)、ロジック、APIなど、それぞれの動作確認工数も考慮する
 - 設計の詳細が不十分なまま実装を始めてしまい、開発しながら設計を考えることになった結果、設計書の更新が後手に回ってしまった
     - 設計者と実装者が違うため、資料だけでは読み取れないものがあったため、自分で設計考えながら実装した方がはやいなとなってしまっていた
     - 効率性を考えると、設計者と実装者は一致させたい
     - 仮に別れる場合は、より詳細で伝わる設計書を作成する
         - システム独自の、普段使わない言い回しは避ける
        - 外部システムの仕様がわかる資料を必ず貼る
        - TBDや論点が残ってる場合は、必ず吹き出しなどでわかるようにしておくなど
    - 「とりあえず実装」だと、設計に手戻ったり、調整ごと(他システムとの調整)が後手に回ってしまうことがある
        - 実装中に設計上の問題が発生した場合には設計に戻り、設計書を更新してから実装に戻る
- コードを書くスピードが遅い
    - 早く成果物を出すためにはとにかく手を動かすことだと考えてしまっていた
    - どう作るかを頭の中だったりメモに残してから作業すると、作業スピードが格段に上がる
    - すぐに手を動かさず、作りをイメージしてから作業に取り組む
- 他の人に仕様に関して質問されると、コード見て調べればええやん...と思ってしまっていたこと
    - コードから読み取って！と言いまくっていたら質問や問題が多発して自分の作業時間がなくなってしまった
    - メモベースでもいいから、「自分のために」共通管理している場所にドキュメントを残す
「個人的」読む事にした文献

有用な文書にすぐ飛ぶ為の場所
忘れないようにもしたい

### Frontend

#### Javascript

https://jsprimer.net/


#### Vue.js
Vue.jsのチュートリアル

https://ja.vuejs.org/tutorial/#step-1

#### Node.js

https://nodejs.org/ja/learn/getting-started/introduction-to-nodejs

#### EXPRESS

https://expressjs.com/ja/

### HTML

https://developer.mozilla.org/ja/docs/Web/HTML/Reference


### API
Microsoft API Design Guidelines
APIの設計原則や推奨されるパターンについて説明されている。

https://learn.microsoft.com/en-us/azure/architecture/best-practices/api-design



### Cloud

#### Azure

https://learn.microsoft.com/ja-jp/azure/?product=popular

#### GCP

https://cloud.google.com/docs/?hl=ja


### エンジニアとしての心構え，意識する事