OmniAICreator/Qiita-1.07M huggingface dataset:
VScode 環境構築&おすすめ拡張機能　AppleシリコンMac編

## VSCodeとは
 Microsoftが提供をしているコードエディターのことです。

 ## VSCodeのダウンロード&インストール
以下がVSCodeの公式サイトです。こちらのリンクから飛べます
[VSCode](https://code.visualstudio.com/)

VSCodeでZipファイルがダウンロードできたら
Zipファイルを解凍しappフォルダにコピーをします。


## VSCodeの起動と日本語化
インストールができたVSCodeのアイコンを押して起動をします。
![スクリーンショット 2024-11-07 23.29.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3590839/0488100b-edf0-f2f5-c13c-9bfd6a2af0ef.png)

VSCodeを起動すると英語で書かれていると思います。
それを日本語化するにはまず、
![スクリーンショット 2024-11-07 23.31.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3590839/44fd69f2-4b00-d60e-120a-11a99b483731.png)
四角い赤色で囲った部分（拡張機能）のところを押します。
そうして、検索バーにJapaneseと入力することで、以下の画像のようなものが出ます。
![スクリーンショット 2024-11-07 23.32.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3590839/8310d342-ae84-1429-ff87-ee80fea3f90d.png)
これをインストールすることで日本語化できます。

## コマンドライン(ターミナル）からのVSCodeの起動
これは、ターミナル上で`code .`とコマンドを入力することによってその場所のディレクトリをVSCodeで開くことができます。
以下が手順です。
1. VSCodeの起動
2. コマンドパレット(⌘+shift+P)を開く、`Shell Command`と入力
![スクリーンショット 2024-11-07 23.50.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3590839/0e88eaff-f8d9-483c-3ed5-fc116c355f48.png)

3. シェル　コマンド: PATH内に`code`コマンドをインストールしますを押す
4. `code`コマンドをインストールする
5. ターミナルを開き、開きたいディレクトリまで移動をして　`code .`と入力するとVSCodeが開く
開けたら完成です。

## おすすめ拡張機能

[Prettier - code formatter](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)

HTML,CSS,JavaScriptなど書くときに形を整えてくれる
![スクリーンショット 2024-11-08 0.06.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3590839/3f6e976b-607a-89fe-ac2c-2821cd9f34fd.png)

[indent-rainbow](https://marketplace.visualstudio.com/items?itemName=oderwat.indent-rainbow)

インデントがとてもわかりやすくて便利！
Pythonを使うときにとても使いやすい
![スクリーンショット 2024-11-08 11.02.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3590839/540a79bf-f691-d250-5298-2347f22ecabb.png)

[Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer)

HTML,CSS,JavaScriptなどのWeb開発をするときに便利
サーバーを立ち上げてくれる！
![スクリーンショット 2024-11-08 11.07.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3590839/51071776-3c84-460b-15da-bce626c48dad.png)
【備忘録】OpenAPIからredocでAPIドキュメント生成 + TS型定義を生成してnpmレジストリに公開するGitHub Actionsを作成する

# はじめに
以下2点を`GitHub Actions`で実行する備忘録です。
- `OpenAPI`から`redoc`でAPIドキュメントを生成して`GitHub Pages`にデプロイする
- `OpenAPI`から`TypeScript`型定義を生成して`npm`レジストリに公開する

## redoc側のActions
```.github/workflows/deploy-redoc.yml
name: OpenAPIをredocとしてgithub pagesにデプロイする

on:
  push:
    branches:
      - main
    paths:
      - "openapi/*" # OpenAPIのyamlだけをCI対象にする
  workflow_dispatch: # 手動実行用

jobs:
  build-redoc:
    runs-on: ubuntu-latest
    steps:
      # リポジトリを取得する
      - uses: actions/checkout@v4

      - name: redocを生成する
        run: npx @redocly/cli build-docs ./openapi/openapi.yaml -o ./docs/envhub-api-docs.html

      - name: artifactsとして生成したredocを保存する
        uses: actions/upload-pages-artifact@v3
        with:
          path: ./docs

  deploy-redoc:
    needs: build-redoc
    runs-on: ubuntu-latest
    permissions:
      pages: write
      id-token: write
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
      
    steps:
      - name: GitHub pagesにデプロイする
        id: deployment
        uses: actions/deploy-pages@v4
```

## TypeScript型生成側のActions
```.github/workflows/publish-npm-typescript.yml
name: OpenAPIからTypeScriptの型定義を作成してnpmにpublishする

on:
  push:
    branches:
    - main
    paths:
      - "openapi/*" # OpenAPIのyamlだけをCI対象にする
  workflow_dispatch: # 手動実行用

jobs:
  build-typescript:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write

    steps:
      # リポジトリを取得する
      - uses: actions/checkout@v4

      # publishするために.npmrcに認証情報を読み込む
      - uses: actions/setup-node@v4
        with:
          node-version: '20.x'
          registry-url: 'https://registry.npmjs.org'

      - name: npm installする
        run: npm install --ignore-scripts

      - name: TypeScriptの型定義を生成する
        run: npx @hey-api/openapi-ts -i openapi/openapi.yaml -o src/client -c @hey-api/client-fetch

      - name: 生成したTypeScriptの型をnpmに公開できるようにトランスパイルする
        run: npx tsc

      - name: npmにpublishする
        run: npm publish --provenance --access public
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
```

## 使い方
**1.** `openapi/openapi.yaml`を編集する
**2.** `package.json`の`version`を上げる
**3.**`main`に`push`する

# さいごに
以下リンクが実装したリポジトリです。

https://github.com/warabimochi1126/EnvHub-openapi/tree/main
EquippableComponent を覗き見る

# はじめに
この記事は Equipment についてプラグインの側からできることについて書いたものです。
定義ファイルの書き方やモデルの作成方法などについては解説していませんので予めご了承下さい。

この記事は主に PaperMC の JavaDoc を基にして書かれています。
そのため Spigot などでは実装や挙動に多少の差異が含まれている可能性があります。

[PaperMC JavaDoc 1.21.3 EquippableComponent](https://jd.papermc.io/paper/1.21.3/org/bukkit/inventory/meta/components/EquippableComponent.html)

# EquippableComponent とは?
Minecraft Java Edition 1.20.5 か 1.21 あたりで追加された、アイテム装着時に色々な効果をもたらす動作の定義を行うコンポーネントのこと。
名前が近い EquipmentSlot とは別物です。

`ItemMeta` のフィールドであり、API 利用者側での初期化はできません。
効果やその発動条件などはほぼすべてデータパック内で管理するため、プラグイン側で出来ることはあまりありません。

# プラグインからできること
- データパック側で作成した定義を（取得・アイテムに適用）する
- 装着可能なエンティティの種類を（取得・設定）する
- 装着可能な装備スロットを（取得・設定）する
- ダメージを受けた際に耐久が削れる（かどうかを取得・ように設定）する
- ディスペンサーで射出して装備できる（かどうかを取得・ように設定）する
- 装備したときにならす音を（取得・設定）する
- 装着したときの外観に適用するモデルを定義したファイルの名前空間を（取得・設定）する
- 装備をインベントリ内などで右クリックしたときに、既存の防具と同じように装着される（かどうかを取得・ように設定）する

装着可能なエンティティの制限、装着時の音、スロット制限以外では真偽値を取得・設定するか、名前空間 (NamespacedKey) を指定する以外できることがありません。

# 使用例

データパック `datapack-name` の `assets/datapack-name/models/equipment/namespace.json` に配置された定義ファイルに記載されている内容を鉄のレギンスに適用する例

```Kotlin
val item = ItemStack(Material.IRON_LEGGINGS)
item.editMeta { meta ->
  meta.setEquippable(meta.equippable.apply {
    slot = EquipmentSlot.LEGS
    model = NamespacedKey("datapack-name", "namespace")
  }
})
```

`datapack-name` の部分にはデータパックの名前空間(`assets/~~~/models` の `~~~`)を、"namespace" には定義ファイルを示す文字列を入れます。(`assets/~~~/models/equipment/***.json` の `***`)

定義ファイルで `humanoid`, `humanoid_leggings` といったようにきちんと定義をしていると、上記のコードで設定したアイテムを装備したときの外観が変わります。
cssについて

# m(__)m
### 1. **レイアウトに関するプロパティ**
- **display**  
  要素の表示方法を指定します。例えば、`block`、`inline`、`flex`、`grid`など。
  
  ```css
  .container {
    display: flex;
  }
  ```

- **position**  
  要素の位置指定を行います。`static`（デフォルト）、`relative`、`absolute`、`fixed`、`sticky`などがあります。

  ```css
  .header {
    position: fixed;
    top: 0;
  }
  ```

- **flexbox（flex）**  
  要素を行または列に並べるためのレイアウト方法です。`display: flex;` を使うことで、子要素の配置を簡単に制御できます。

  ```css
  .container {
    display: flex;
    justify-content: center;
  }
  ```

- **grid**  
  2次元のレイアウトシステムで、`display: grid;`を使用します。

  ```css
  .grid-container {
    display: grid;
    grid-template-columns: 1fr 1fr;
  }
  ```

- **float**  
  要素を左または右に浮かせ、テキストや他の要素を回り込ませるために使います。

  ```css
  .image {
    float: left;
    margin: 10px;
  }
  ```

### 2. **フォントとテキストに関するプロパティ**
- **font-family**  
  使用するフォントを指定します。

  ```css
  p {
    font-family: "Arial", sans-serif;
  }
  ```

- **font-size**  
  フォントサイズを指定します。

  ```css
  h1 {
    font-size: 36px;
  }
  ```

- **font-weight**  
  フォントの太さを指定します。`normal`、`bold`、`lighter`など。

  ```css
  p {
    font-weight: bold;
  }
  ```

- **text-align**  
  テキストの整列方法を指定します。`left`、`right`、`center`、`justify`など。

  ```css
  .container {
    text-align: center;
  }
  ```

- **line-height**  
  テキスト行間の高さを指定します。

  ```css
  p {
    line-height: 1.5;
  }
  ```

### 3. **色に関するプロパティ**
- **color**  
  テキストの色を指定します。

  ```css
  h1 {
    color: #ff0000;
  }
  ```

- **background-color**  
  要素の背景色を指定します。

  ```css
  .header {
    background-color: #f0f0f0;
  }
  ```

- **border**  
  要素に枠線を追加します。

  ```css
  .box {
    border: 1px solid #000;
  }
  ```

### 4. **ボックスモデルに関するプロパティ**
- **width** と **height**  
  要素の幅と高さを指定します。

  ```css
  .box {
    width: 200px;
    height: 100px;
  }
  ```

- **padding**  
  要素の内側の余白を指定します。

  ```css
  .container {
    padding: 10px;
  }
  ```

- **margin**  
  要素の外側の余白を指定します。

  ```css
  .container {
    margin: 20px;
  }
  ```

- **box-sizing**  
  `width` と `height` にどこまでを含めるかを設定します。`border-box` では `padding` と `border` を含めて計算します。

  ```css
  .box {
    box-sizing: border-box;
  }
  ```

### 5. **その他のプロパティ**
- **opacity**  
  要素の透明度を指定します。`0` が完全に透明、`1` が完全に不透明。

  ```css
  .overlay {
    opacity: 0.5;
  }
  ```

- **transition**  
  プロパティの変化に対してアニメーションを追加します。

  ```css
  .button {
    transition: background-color 0.3s ease;
  }

  .button:hover {
    background-color: #007bff;
  }
  ```

- **box-shadow**  
  要素に影を追加します。

  ```css
  .box {
    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.5);
  }
  ```

- **transform**  
  要素を回転、スケーリング、移動などの変形を行います。

  ```css
  .box {
    transform: rotate(45deg);
  }
  ```

- **z-index**  
  要素の重なり順序を設定します。大きい値ほど手前に表示されます。

  ```css
  .box {
    z-index: 10;
  }
  ```

### 6. **メディアクエリ（レスポンシブデザイン）**
CSSで画面サイズに応じてスタイルを変更する方法です。

```css
@media (max-width: 600px) {
  .container {
    background-color: #f8f8f8;
  }
}
```

### まとめ
CSSには非常に多くのプロパティがあり、タグや要素に対して詳細なスタイル指定が可能です。上記は代表的なプロパティですが、CSSの全てのプロパティを網羅するには膨大なリストになります。必要に応じて、公式ドキュメント（[MDN Web Docs](https://developer.mozilla.org/ja/docs/Web/CSS)）を参照することをおすすめします。


### 今回も真面目系でしたm(__)m
メモ

public static boolean isValidUTF8(String text) {
    try {
        byte[] bytes = text.getBytes("ISO-8859-1"); // 使用ISO-8859-1读取原始字节
        String decoded = new String(bytes, "UTF-8"); // 尝试解码为UTF-8
        String reEncoded = new String(decoded.getBytes("UTF-8"), "ISO-8859-1");
        return text.equals(reEncoded); // 如果重新编码后的结果一致，说明没有乱码
    } catch (UnsupportedEncodingException e) {
        return false;
    }
}
中間コード方式について簡単に

## 概要
- コンパイラ方式とインタープリタ方式の中間的な方法
- 言語特有の環境用機械語にコンパイルし、実行時に逐次実行か機械語に翻訳後実行される
- Java、Pythonで採用

## この方式の特徴と利点
- コンパイラ方式には及ばないが、インタープリタ方式よりは早い
- 一度中間コードにコンパイルするとwindowsでもmacでも動く

## なぜ同じ方式のJavaとPythonで実行速度に差があるのか
- Javaは静的型付け、Pythonは動的型付けであるので型チェックの時間で差が生まれる
- JavaはJITコンパイラでネイティブコードに変換されるがPythonは逐次解釈するから

<script>alert('XSS攻撃!');</script>
IPMI Remote Redirection on Javaのエラー回避方法(IBM Cloud ベアメタル）

IBM Cloudのベアメタルサービスを借りて早数年。
新しいBMCファームウェアではRemote Redirection をHTML5で行われるのが主流となってきましたが、古い機器ではJavaのみで、普通にブラウザから開いても以下のようなエラーで立ち止まってしまう。

```
sun.security.validator.ValidatorException: PKIX path validation failed: 
```

google先生に聞くと証明書をImportしてコンパイルする・・・という正攻法が紹介されていますが、
今回はともかくそこはセキュリティレベルを下げてでも容認する方向で（単に手順が複雑なのでちかよりたくない）、この記事を書きます。

# Java Runtimeのインストール

java.comからダウンロードインストールしましょう。

# java.securityファイルの編集

java.securityファイル上のパラメーターを編集したい。

Windowsの場合は

```
C:\Program Files\Java\jre1.8.0_431\lib\security
```
のようなフォルダに格納されている。（バージョン次第でフォルダ名かわる）

java.securityファイルをコピー・バックアップし、以下に編集

## 今の状態

```
jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, \
    RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224, \
    include jdk.disabled.namedCurves, \
    SHA1 usage SignedJAR & denyAfter 2019-01-01
```

## 編集後

```
jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, \
    RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224, \
    include jdk.disabled.namedCurves
```

以下を消すと動くらしい。
```
    SHA1 usage SignedJAR & denyAfter 2019-01-01
```


# Javaのエラー再び。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126158/526ad020-1294-ef0e-c22d-bc45f8d6a181.png)

こちらはJavaの構成→セキュリティ→例外サイト・リスト→で該当のIPMI URLを記載。

# IPMIコンソール出現

無事完了です。


# TODO
ベアメタルのファームウェアをアップデートしたらHTML5対応になるのか？（なったらうれしいけど・・・
MarkdownのQiita，Zenn，GitHubの独自記法を変換するブラウザExtensionsを作ってみた

## これは何?

はじめてBrowserのExtensionsを作ってみたのですが，想像よりも敷居が低くJSの勉強になりそうだったので布教します。

---

## Browser Extensionsに関する個人的な誤解

- ブラウザの仕組みとかよくわかってないので難しそう→manifest.jsonを書いて普通にWebアプリを作るだけ
- Google ChromeとFirefoxの両対応大変そう→manifest.jsonの構文的には変わらないのでそのまま流用できるケースもありそう。

---

## 作ったもの
[md_converter](https://github.com/RyosukeDTomita/md_converter_extensions/blob/main/README.md): 以下のようなNOTE記法をブラウザのExtensionsで変換して，変換後のものをclipboardにコピペできるようにしました。

正規表現を使って置換しているだけで技術的に難しいことはしていません。

```
# GitHub

> [!NOTE]
> this is note
> hi
```

```
# Qiita

:::note info
this is note
hi
:::
```

```
# Zenn

:::message
this is note
hi
:::
```

![Screenshot from 2024-11-08 10-22-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3718390/076b2890-af86-7b75-439f-41de938d6e68.png)

## Browser Extension開発の良いと思うところ

- サーバ台がかからない
- すぐに動くものが作れる
- ストアに公開とかしても楽しそう

---

## 今後の活動
- せっかくなのでVueとかReactとかで書き直してみたい。
- もう少しBrowserに干渉するようなものを作れたら楽しそう。↓これとか参考になりそう

https://www.udemy.com/course/chrome-extension/
円安時代のWEB開発保守

本記事は、 [mediba Advent Calender2024](https://qiita.com/advent-calendar/2024/mediba) の1日目の記事になります。

## 円安対策

GPT先生に聞いてみました :ear: 

- https://chatgpt.com/share/674c0bb5-be80-800e-a6b1-3b678f1b32c0

いずれも金融スキルが求められる内容ですが、4の`ローカルサービスの利用`は、現場でも着手出来そうな内容ですね。
Pontaパスの保守開発では、前期(23年度下期)比で1,500万円程度のAWS費用(請求額ベース)を削減することが出来ました :money_mouth: 
今回は、その一部始終を紹介致します :pen_ballpoint: 

## チームで現状把握

まずは、現状把握です。
これには、[Billing and Cost Management console](https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/view-billing-dashboard.html)が最適です。
一昔前ですと、リセラーのダッシュボードを利用していましたが、コンソールで確認できるようになっていました。
Pontaパスの保守開発では、[Cost Explorer](https://docs.aws.amazon.com/cost-management/latest/userguide/ce-what-is.html)を有効化し、コストインパクトがあるリソースや、コストの変遷を定例ミーティングで確認、共有するようにしています :microphone2: 
現状、リソース削除は、リスクを伴う作業であり、複数人で行う必要があります。
チームで現状を把握し、アクションに繋げることがポイントです :up: 

## 安心安全なリソース削除のために

リソース削除は、リスクを伴う作業です。
そのためか、私が前任者から引き継いだPontaパスの各AWSアカウントでは、不要もしくは遊休リソースが増加傾向で、雪だるま式にコストも増加するという悪循環にありました。
リソース削除がシステム稼働に与えるリスクだけでなく、意思決定者に向けた説明といった要素も考慮すると、不測の事態への備えは必要です。
Pontaパスの保守開発では、AWSリソースの管理に[terraform](https://www.terraform.io/)を利用していますので、削除対象のリソースでコード化されていないものは、[import](https://developer.hashicorp.com/terraform/cli/import)するなどして、不測の事態の際は切り戻せるようにしています。
また、諸々の事情で遊休状態となっているリソースについては、削除するが任意のタイミングで復旧(稼働状態とする)させることを条件に意思決定者との合意を得るプロセスを踏んでいます。
その際は、以下のような対応を取っています。
- データのバックアップを取得
- [terraform destroy](https://developer.hashicorp.com/terraform/cli/commands/destroy)で遊休リソースを削除
- terraformのコードは保全されているので、必要に応じてリソースを構築出来るようにしておく
- 手順や経緯を記した資料を必ず残す

リスクを伴う作業ですが、コストの最適化には必要不可欠なフェーズです。
関係者とのコミュニケーションも含め、全方位で対策を取るようにしています。

## おわりに

保守開発が続く限り、対策に終わりはありません。
今回紹介した内容以外にもPontaパスの保守開発では、各種AWSサービスの更新に合わせてシステム構成を変更することでコストを最適することにも取り組んでいます。
機会があれば、その取り組みも紹介したいと思います :pen_ballpoint: 
悩める保守開発現場の一助になれば幸いです :traffic_light: 

---

現在medibaでは、メンバーを大募集しています。

- [募集・応募ページ](https://www.mediba.jp/recruit)

medibaってどんな会社だろう？ と興味を持っていただいた方は、
カジュアル面談もやっておりますので、お気軽にお申込み頂ければと思います。
Goで基本的なアルゴリズム書いてみた


## 概要


基本的なアルゴリズムをGoで書いてみた。


また書いたら追記していく。


## 線形探索


```go
func LinearSearch(array []int, target int) int {
	for i, v := range array {
		if v == target {
			return i
		}
	}
	return -1
}
```


## バブルソート


```go
// 昇順
func BubbleAscSort(array []int) []int {
	n := len(array)
	for i := 0; i < n-1; i++ {
		for j := 0; j < n-1-i; j++ {
			if array[j] > array[j+1] {
				tmp := array[j]
				array[j] = array[j+1]
				array[j+1] = tmp
			}
		} 
	}
	return array
}

// 降順
func BubbleDescSort(array []int) []int {
	n := len(array)
	for i := 0; i < n-1; i++ {
		for j := 0; j < n-1-i; j++ {
			if array[j] < array[j+1] {
				tmp := array[j]
				array[j] = array[j+1]
				array[j+1] = tmp
			}
		} 
	}
	return array
}
```


## 二分探索


```go
func BinarySearch(array []int, target int) int {
	left, right := 0, len(array) - 1

	for left <= right {
		mid := left + (right - left) / 2
		
		if array[mid] == target {
			return mid
		} else if array[mid] < target {
			left = mid + 1
		} else {
			right = mid - 1
		}
	}

	return -1
}
```


つづく。。かも
まだこんな使い方してない？

## 以前の使い方

学生の間で、運用方法が変わっていました。
- add, commit, pushのみ
- SourceTreeなどのGUIツールの使用
- blanch, merge, checkoutの使用
- cherrypick, rebaseの使用

まだ未熟なので、不十分なところもあると思いますが、個人、チームでもこの知識があると一般的な使い方はマスターできるのかと思います。

### 個人開発の運用

タスクの把握は、大雑把でも許容範囲だと思います。なのでローカルだけで完結するタスク管理や、メモ程度でも運用可能です。

### チーム開発の運用

タスクの透明化をすることで、スケジュール感や、ヘルプを出せたり、チーム全体として把握が容易くなります。GitHubなどの共有しやすいツールを使うことで透明化を図ることができます。個人的な意見なのですが、使用ツールを増やせば良いということではない、むしろ一貫性を持たず、工数の増加にもなりうると考えます。

### GitHubでの運用

ベストプラクティスとまではいかないですが方法の一つとして参考程度に

:::note info
issueをタスク管理として使用しています
:::

1. issueを立てる
issue_templateを使って、issueの足の重さを軽減

2. issue番号を含めてブランチを切る
issueに関連付けする目的

3. 作業後コミット
git-czを使って、コミットメッセージの統一化（commitlintで強制もできます）

4. pull_requestの作成
pull_request_templateを使用してレビュアーにわかりやすいPR

5. レビュー 

## まとめ
今までのgitの運用方法が悪いものではないし、開発規模や期限によりベストプラクティスなりうるものだと思いました。なので運用方法はチーム内で認識をすり合わせてきちんと決めるべきだと感じました。おしまい
TiDB 関連イベント 11月分

10月がいつ終わったか記憶にない...

恒例のイベント案内11月分です！

PingCAP主催のもの、コミュニティイベントに参加するものの両方を記載しています。
WebinarについてはJSTで6:00-24:00に開催されるイベントを記載しています。

また、ここに記載がなくとも、イベント/社内勉強会でTiDBについて話してほしいというリクエストはお気軽に @bohnen ([X/@bohnen](https://twitter.com/bohnen)) までお気軽にご連絡ください。

## 【お知らせ】TiDB User Dayのアーカイブ視聴が可能になりました！ 

https://pingcap.co.jp/tidb-user-day/

7月3日に行われたTiDB User Dayのセッションアーカイブが公開されました。是非登録して御覧ください。

## （終了）ウェビナー: TiDBとTiDB Cloud最新状況の紹介

https://pingcap.co.jp/event/tidb-and-tidb-cloud-status-update/

この記事を書くのが遅くて、すでに終了していますが、TiDBとTiDB cloudのアップデートおさらいのウェビナーです。講師はおなじみPingCAP本田さんです。すぐにアーカイブ配信があると思いますのでチェックしてみてください。


## ウェビナー: NewSQL時代のデータベース開発・運用の成功法則

https://products.sint.co.jp/siob/seminar/20241119

SI Object Browserで有名な株式会社システムインテグレーター様のウェビナーでお話させていただきます！SI Object BrowserはOracleでシステム開発をしたことがある方ならご存知ではないでしょうか。
今回、MySQL対応版がリリースされ、TiDBも利用できます！ 

トピックとしてはTiDBの話というよりも、NewSQLの紹介と、なぜ今NewSQLが話題になっているのかというところについてのご紹介が主になります。NewSQLについて知りたい方はぜひご参加ください。

## CEDEC+KYUSHU 2024

https://pingcap.co.jp/event/cedeckyushu2024/

CEDECの九州版であるCEDEC+KYUSHUにPingCAPは協賛しています。
ゲーム好きとしても参加したいイベントですね！特に発表などは今回ありませんが、どのセッションも非常に興味深く、ゲーム業界以外の方にも参考になるのではないでしょうか。

## アーキテクチャカンファレンス2024

https://architecture-con.findy-tools.io/2024/sessions?m=2024/mdl/special/rVkGBTUy

Neal Ford来日？！ っていうのでまず驚くアーキテクチャカンファレンス2024、こちらのイベントも協賛しています。TiDBユーザーのSUPER STUDIO様と当社SA日下のセッションです。お見逃しなく！
またブースも出していますので、ぜひお立ち寄りください。

## 来月はアドベントカレンダーの月です！

来月はいよいよ年の瀬、12月です。Qiitaアドベントカレンダーにも参加予定ですので、皆さんTiDBのBlogを書き溜めておいてください！
CloudFrontの標準ログ (アクセスログ)をCloudShellとDuckDBで気軽に分析する

## 背景

CloudFrontのログはS3に保存されますが、そのままでは分析しにくいという課題があります。
これまでの方法としてS3 Selectを使用することがありましたがサービスの終了がアナウンスされ、また、Athenaを利用する場合はやや面倒くささを感じていました。
このため、ここではCloudShell上でDuckDBを利用して直接S3からデータを取り込むことで手軽に分析してみようと思います。


## 手順
1. CloudShellを起動します
    `cloudshell`と`s3`のポリシーを持ったiamでawsマネジメントコーンソールにログインし、CloudShellを立ち上げます
2. DuckDBをインストールします
    [DuckDB Installation Guide](https://duckdb.org/docs/installation/index)  
    バージョン部分は必要に応じて変更してください
   
    ```shell
    wget https://github.com/duckdb/duckdb/releases/download/v1.1.3/duckdb_cli-linux-amd64.zip
    unzip duckdb_cli-linux-amd64.zip
    ```
3. duckdbを起動し、ログを読み込みます
    duckdbを起動
    
    ```shell
    ./duckdb
    ```

    duckdb上で以下のsqlを流してテーブルを作成
    s3のファイル名部分は対象となるファイルをいい感じに指定してください。複数も可能で、またglobでの表現も可能です。

    ```sql
    CREATE SECRET s3_secret (
        TYPE S3,
        PROVIDER CREDENTIAL_CHAIN
    ); 
    
    CREATE TABLE logs AS
    FROM read_csv(['s3://<バケット名>/<cloudfrontのID>.YYYY-MM-*.gz'],
        header = false,
        skip = 2,
        columns = {
        'date': 'DATE',
        'time': 'TIME', 
        'x-edge-location': 'VARCHAR',
        'sc-bytes': 'BIGINT',
        'c-ip': 'VARCHAR',
        'cs-method': 'VARCHAR',
        'cs(Host)': 'VARCHAR',
        'cs-uri-stem': 'VARCHAR',
        'sc-status': 'BIGINT',
        'cs(Referer)': 'VARCHAR',
        'cs(User-Agent)': 'VARCHAR',
        'cs-uri-query': 'VARCHAR',
        'cs(Cookie)': 'VARCHAR',
        'x-edge-result-type': 'VARCHAR',
        'x-edge-request-id': 'VARCHAR',
        'x-host-header': 'VARCHAR',
        'cs-protocol': 'VARCHAR',
        'cs-bytes': 'BIGINT',
        'time-taken': 'DOUBLE',
        'x-forwarded-for': 'VARCHAR',
        'ssl-protocol': 'VARCHAR',
        'ssl-cipher': 'VARCHAR',
        'x-edge-response-result-type': 'VARCHAR',
        'cs-protocol-version': 'VARCHAR',
        'fle-status': 'VARCHAR',
        'fle-encrypted-fields': 'VARCHAR',
        'c-port': 'BIGINT',
        'time-to-first-byte': 'DOUBLE',
        'x-edge-detailed-result-type': 'VARCHAR',
        'sc-content-type': 'VARCHAR',
        'sc-content-len': 'VARCHAR',
        'sc-range-start': 'VARCHAR',
        'sc-range-end': 'VARCHAR'
    });
    ```
    しばらく(数分？)時間かかります

    ここまでで読み込みが完了し、以後はサクサクとlogに対してsqlで分析することができます
    ```sql
    select * from logs;
    ```

4. テーブルを出力
    このままだとduckdbを終了すると読み込んだテーブルが消えるので、データ出力しておきます
    ```sql
    COPY (SELECT * from logs) TO 'logs.parquet' (FORMAT parquet, COMPRESSION zstd);
    ```

    次回起動したときは以下のように読み込みます
    ```sql
    CREATE TABLE logs AS FROM read_parquet('logs.parquet');
    ```

## メリットと注意事項
このやり方のメリットとしては、特に手元に環境を用意せず即座に分析を行えるところにあると思います。また、s3と同じリージョンでCloudShellを実行すれば、料金もかからないような気がします(※未検証)

ただ、CloudShellはインスタンスのメモリやストレージのサイズが大きくなく、CloudFrontのアクセスが多い場合にログのサイズが大きくなり、メモリやストレージが不足して満足に分析できなくなる可能性があります。その場合は、読み込むログファイルを減らしたり、手元のマシンでDuckDBを動かしたり(その場合はs3のダウンロード料金はかかる)、いっそAthenaで分析をするなどしたほうがいいかもしれません。

## 参考
https://qiita.com/tsukamoto/items/4f798228b35c55753346#s3-select
https://road288.hatenablog.com/entry/2024/11/06/113954
https://zenn.dev/shiguredo/articles/duckdb-jsonlines-log