jedipunkz 🚀 のブログ

SRE になるために学んでいくブログです

Zig 入門: 構文集

こんにちは @jedipunkz です。 コーディングを学習する機会を増やしている最中なのですが、自分は底レイヤが好きなのを思い出し、またたまに Mitchell Hashimoto 氏が Zig のことを呟いてるのを覚えていたので、突然 Zig に入門したくなりました。 ということで後に自分でも読み返せる形にしようと思い Zig の構文集を記します。 NOTICE ※ 現時点で Stable な 0.15.1 を前提に記します。 ※ 気が向いたときに言語仕様の変化に対応して修正していこうと思います。 はじめに このドキュメントは、Zig 言語の主要な構文を網羅的にまとめたチュートリアルです。すべてのサンプルコードは記事の修正時点で Stable なリリースバージョンの Zig で動作確認しています。 目次 基本構文 演算子 制御構文 関数 配列とスライス 構造体 列挙型とユニオン ポインタ エラーハンドリング オプショナル型 コンパイル時計算 メモリアロケータ テスト モジュール 1. 基本構文 変数宣言 Zig には 2 種類の変数宣言があります。const は不変変数(再代入不可)、var は可変変数(再代入可能)を表します。 const cat: i32 = 5; // const: 不変変数(再代入不可) var dog: i32 = 10; // var: 可変変数(再代入可能) dog = 15; // OK // cat = 10; // エラー: const は変更不可 型推論 型を明示的に指定しなくても、コンパイラが自動的に型を推論してくれます。 ...

TypeScript 入門: 構文集

こんにちは @jedipunkz です。 TypeScript の学習を進める中で構文を網羅的に理解する必要性を感じてサンプルコード作成を作成し動作確認した上で構文集を作成しました。この記事では TypeScript の主要な構文をまとめたいと思います。 ※ 気が向いたときに新しい構文が出てきた際に更新し続ける記事にしようと思っています。 目次 1. 基本的な型システム プリミティブ型 型注釈と型推論 TypeScript 拡張型 リテラル型 型アサーション 2. 複合型 配列とタプル オブジェクト型 ユニオン型とインターセクション型 列挙型 Discriminated Unions 3. 関数 関数の型定義 関数のオーバーロード 4. インターフェース 基本的なインターフェース インターフェースの継承 5. クラス クラスの基本 アクセス修飾子 継承と抽象クラス 6. ジェネリクス ジェネリクスの基本 型制約とユーティリティ型 7. 型エイリアス 8. モジュール エクスポートとインポート 9. 高度な型機能 型ガード 高度な型演算子 インデックスシグネチャ ユーティリティ型の拡張 Mapped Types 条件付き型 10. 高度な機能 デコレーター 名前空間 基本的な型システム プリミティブ型 プリミティブ型は JavaScript の基本的なデータ型です。TypeScript ではこれらに型注釈を付けることで型安全性を確保できます。 boolean 型 - 真偽値を表します。true または false のいずれかの値を持ちます。 number 型 - 数値を表します。整数・小数・16 進数・2 進数・8 進数すべてこの型で扱います。JavaScript と同様に内部的にはすべて浮動小数点数として扱われます。 string 型 - 文字列を表します。ダブルクォート、シングルクォート、バッククォート(テンプレートリテラル)で記述できます。 null 型と undefined 型 - 値が存在しないことを表します。null は明示的に値がないことを示し、undefined は値が未定義であることを示します。 bigint 型 - Number.MAX_SAFE_INTEGER を超える大きな整数を扱えます。末尾に n を付けて記述します。 symbol 型 - 一意で不変の値を作成します。オブジェクトのプロパティキーとして使用されることが多いです。 // 基本的な型 const dogName: string = "Buddy"; const dogAge: number = 3; const isDogHungry: boolean = true; console.log(dogName); // 出力: Buddy console.log(dogAge); // 出力: 3 console.log(isDogHungry); // 出力: true // null と undefined const location: null = null; let age: undefined = undefined; console.log(location); // 出力: null console.log(age); // 出力: undefined // bigint と symbol const weight: bigint = 9007199254740991n; const id: symbol = Symbol("unique"); console.log(weight); // 出力: 9007199254740991n console.log(id); // 出力: Symbol(unique) 型注釈と型推論 型注釈 (Type Annotation) は変数や関数に明示的に型を指定する機能です。: 型名 の形式で記述します。型注釈によりその変数や関数が扱える値の種類を明確にできます。 ...

Terraform Plan 差分をパースする GitHub Actions を作った

こんにちは。jedipunkz🚀 です。 Terraform を運用しているとたまに Plan 結果がどうしても出てしまう事があります。また Terraform を GitHub で実行する環境を運用していると Plan 結果をうまく扱って自動化したいモチベーションも湧いてきます。この場合に Plan の差分をうまく処理してくれる GitHub Action があればなと思って作ってみました。 GitHub Actions 作成した GitHub Action は下記のレポジトリで公開しています。 https://github.com/jedipunkz/tf-plan-parser 入力・オプション設定 この GitHub Action では2つの入力オプションが利用可能です: terraform-plan (必須) パース対象となる Terraform Plan の出力結果を指定します。通常は前のステップで実行した terraform plan コマンドの標準出力を渡します。 ignore-resources (オプション) 無視したいリソースタイプや特定のリソースを配列形式で指定します。デフォルトは空の配列 [] です。 指定方法の例: リソースタイプ全体を無視: ignore-resources: '["null_resource", "local_file"]' 特定のリソースインスタンスを無視: ignore-resources: '["null_resource.temporary", "local_file.cache"]' リソースタイプとインスタンスの混在: ignore-resources: '["null_resource", "aws_s3_bucket.temp", "local_file"]' 出力される情報 この Action は以下の出力を提供します。また下記は ignore-resources オプションの指定に沿って結果を出力してくれます。 diff-bool: 変更があるかどうかの真偽値(true または false) diff-count: 変更されるリソースの数 diff-resources: 変更されるリソースのアドレス一覧(カンマ区切り) diff-raw: 生の差分データ diff-json: s分データの JSON 形式 これらの出力を使って、後続のステップで条件分岐や通知の制御が可能です。 ...

Go 初学者が学ぶクリーンアーキテクチャ

自分は Go の初学者なのですがクリーンアーキテクチャを学ぶために幾つかの書籍を読んでみたもののなかなかしっくりと理解が出来ていない状態でした。 そこで AI に極力シンプルなコードを書かせて理解するという事をやってみたのですが、なかなかいい感じに理解が進んだのでここで記事にしたいと思っています。 クリーンアーキテクチャとは? クリーンアーキテクチャは、Robert C. Martin によって提唱されたソフトウェア設計原則で最も重要な特徴は依存関係の方向性にあります。 従来のアーキテクチャとは異なり、内側の層は外側の層を知らないという原則に基づいています。これにより以下のメリットが得られます。 テスタビリティ: ビジネスロジックを単体でテスト可能 柔軟性: データベースや Web フレームワークの変更が容易 保守性: 関心の分離により変更の影響範囲を限定 実装するシステムの全体像 今回 AI に実装させたのは RESTful API を提供するユーザー管理システムです。 コードは下記のレポジトリにあります。 https://github.com/jedipunkz/go-clean-architecture-playground システムは以下の4つの層で構成されています: Entity レイヤ - ビジネスの核となるルール Interface レイヤ - 抽象化による疎結合 Use Case レイヤ - ビジネスロジックの実装 Infrastructure レイヤ - 外部システムとの連携実装 Controller レイヤ - HTTP APIの提供 各層の詳細実装 1. Entity レイヤ - ビジネスの核となるルール 最も内側の層から実装を始めます。エンティティ層は他のどの層にも依存しない純粋なビジネスロジックです。 // entity/user.go package entity import ( "errors" "time" ) type User struct { ID int `json:"id"` Name string `json:"name"` Email string `json:"email"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } func NewUser(name, email string) (*User, error) { if name == "" { return nil, errors.New("名前は必須です") } if email == "" { return nil, errors.New("メールアドレスは必須です") } now := time.Now() return &User{ Name: name, Email: email, CreatedAt: now, UpdatedAt: now, }, nil } func (u *User) UpdateInfo(name, email string) error { if name == "" { return errors.New("名前は必須です") } if email == "" { return nil, errors.New("メールアドレスは必須です") } u.Name = name u.Email = email u.UpdatedAt = time.Now() return nil } この User エンティティは、クリーンアーキテクチャの最も内側に位置する部分です。ここで重要なのは、このエンティティが外部の何にも依存していないことです。データベースがMySQLなのかPostgreSQLなのか、WebフレームワークがGinなのかEchoなのか、そういった技術的な詳細は一切知らないのが特徴になっています。 ...

MCP の理解: Platform Enabler/SRE での活用

自分は Platform Enabler/SRE として従事しています。また AI 関連のアップデートは2025年に入っても属に更新されています。2025年初頭においては自分たちの分野でも AI 関連の利用に関して様々な模索がある状況だと思われますが、Ahthoropic 社が提唱した MCP (Model Context Protocol) がもたらすインパクトはアプリケーションに限定されずインフラ領域のソフトウェアにも大きなメリットをもたらすと思って観測しています。 この記事では、MCP の概要とどう実装するのかの学習、またどう我々のような Platform Enabler/SRE にとっての活用例があるかを考察していきたいと思っています。 MCP の概要 MCP (Model Context Protocol) は、AI モデルと外部システム間のやり取りを効率化するプロトコルで JSON-RPC でやりとりします。ユーザーの自然言語入力を基に、AI アシスタントが MCP サーバーを通じてファイル操作やデータ処理を実行します。 最近 OpenAI 社もこの Anthropic 社の MCP をサポートするというニュースが流れ、途端に注目を集める状況になってきました。 処理の流れ ここはあくまでの一例です。Assistant の実装でいかようにも出来ると思います。 +-------------+ +-----------+ +------------+ +--------+ | User Prompt | <-----> | Assistant | ---> | MCP Server | | AI API | +-------------+ (1),(5) +-----------+ (3) +------------+ +--------+ | ^ | (2),(4) | +----------------------------------+ (1) ユーザからの入力を Assistant が受け取る (2) Assistant はユーザからの自然言語を LLM に問い合わせ。その際に LLM に外部機能を定義 (JSON-RPC(MCP サーバが受け取る)) (3) Aasistant は MCP Server に JSON-RPC でクエリ送信しレスポンスを得る (4) Assistant は MCP Server から得たレスポンスを再び LLM に送信し自然言語としてユーザに返す内容を生成してもらう (5) Assistant はユーザに自然言語で結果を応答する 前提 MCP 学習を目的にしているので、ここでは話を簡潔にするため Linux Filesystem を操作する MCP Server を書き、理解していきます。 ...

VPC Lattice + ECS 構成を Terraform を通して理解

jedipunkz です。VPC Lattice が ECS に対応したという情報が https://aws.amazon.com/jp/about-aws/whats-new/2024/11/amazon-vpc-lattice-elastic-container-service/ にあがりました。この対応を Terraform を使って構成して検証してみるのが今回の目的になります。 今回検証で用いたコード 検証コードは下記に置いておきました。 https://github.com/jedipunkz/vpclattice-ecs-playground 概要 構成の概要としては下記です。(Mermaid 記表でうまく描けていませんが) VPC1, VPC2 に跨る形で VPC Lattice Service Network が配置 VPC2 上の何者か (例で EC2) が VPC1 上の ECS に接続可能 その際は VPC Service Network を介して VPC Lattice Service がエンドポイントとして受ける (うまく描けてない) という事は今まで複数の VPC 間で ECS のエンドポイントを共有しようとすると VPC1, VPC2 とで VPC Peering を張る VPC1 上の Private Subnets 上で ALB を構築して ECS Service に接続する という構成が必要でしたが、VPC Lattice を使えばそれらが不要になる、という事です。 今回検証した構成 今回使った Terraform コードで構築した構成は下記です。各 AWS リソースの関係図になっています。 特徴としては ...

Go, OpenTelemetry で AWS にログ・トレースを計装してみる

OpenTelemetry を使って AWS (X-Ray, Cloudwatch Logs) にトレースとログを計装する事に興味があったので調べた内容を記そうと思います。 構成 今回検証してみた構成は下記の様な構成です。AWS を用いた場合 ECS や EKS, Lambda で Go アプリを起動する事が通常ですが、今回は docker-compose で検証しました。ただ ECS, EKS に置き換えるのは比較的簡単だと思います。 trace post PutTelemetryRecords +--------+ +----------------+ +-----------------+ | Go App | -+-> | Otel Collector | ---> | AWS X-Ray | +--------+ | +----------------+ +-----------------+ | +----------------+ +-----------------+ +-> | Fluent-Bit | ---> | Cloudwatch Logs | +----------------+ +-----------------+ PutLogEvents ログとトレースの紐づけ ログは Cloudwatch Logs へ、トレース情報は AWS X-Ray へ転送しますが、このログとトレースを紐付けると、運用する上で追跡が容易になります。この紐づけは AWS の場合は簡単で下記の要件を満たせば紐づけがされます。 ...

自前開発した Prometheus Exporter で自宅ルータのメトリクス監視運用している話

自宅のルータについても可観測性を向上して普段の運用に役立てています。例えば長期スパンでのネットワーク通信料の推移や CPU, Mem 使用率、あとハードウェアの温度の推移などを観測しています。 今までは Prometheus の Node Exporter を使ってホストの情報を Prometheus Server に提供していたのですが、自分で Go で Prometheus Exporter を書いて運用するにようになったので、それについてまとめます。 Grafana の可視化情報 下記が可視化された情報です。CPU, Mem やネットワーク送信量、またハードウェアの温度を可視化して運用しています。 ソース置き場 結論になりますが下記にソースを置いています。 https://github.com/jedipunkz/linux-tiny-exporter ネットワーク送信・受信メトリクスを説明 実際にはこのコードでは CPU 使用率, Memory 使用率, Disk IO, Network トラヒック, ハードウェア温度を取得・提供しているのですが、ここでは例としてネットワークトラヒックに関するメトリクスを Prometheus Server に提供するコードを説明しようと思います。 パッケージのインポート Prometheus のクライアントライブラリから2つのパッケージをインポートしています。 “github.com/prometheus/client_golang/prometheus”: これは Prometheus の基本的なクライアントライブラリで、メトリクスを定義、収集、エクスポートするための機能を提供します。 “github.com/prometheus/client_golang/prometheus/promhttp”: これは Prometheus の HTTP サーバーとクライアントのためのライブラリで、HTTP 経由でメトリクスを公開するためのハンドラを提供します。 "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" ネットワークトラヒックに関する構造体定義 ここからは Internal Packege のコード解説です。 NetCollector という構造体が定義しています。この構造体は、ネットワークインターフェースごとの受信バイト数、送信バイト数、受信パケット数、送信パケット数の差分を保持します。~Diff はそれぞれの値の差分を保持します。前回のスクレイプ(データ収集)からの変化を表します。 type NetCollector struct { receivedBytesDiff *prometheus.Desc transmitBytesDiff *prometheus.Desc receivedPacketsDiff *prometheus.Desc transmitPacketsDiff *prometheus.Desc lastReceivedBytes map[string]float64 lastTransmitBytes map[string]float64 lastReceivedPackets map[string]float64 lastTransmitPackets map[string]float64 } コンストラクタ NewNetCollector 関数は、新しい NetCollector インスタンスを作成します。この関数では、各メトリクスの差分を表す prometheus.Desc オブジェクトを作成し、それらを NetCollector 構造体の対応するフィールドに設定します。また、前回のスクレイプ時の各メトリクスの値を保持するマップも作成します。 ...