uokadaの見逃し三振は嫌いです

ここで述べられていることは私の個人的な意見に基づくものであり、私が所属する組織には一切の関係はありません。

blackをruffで置き換えてる - Replacement black with ruff

最近、プライベートなpythonプロジェクトでblackをruffで置き換えたのでそのメモ。

ここ数ヶ月の間にblackとruffを導入したんですが、ruff v0.1.2でformatterが導入されたのでblackへの置き換えを小さめなプロジェクトで実施しました。

astral.sh

blackとruff formatのdiff check/formatのコマンド体系はほぼ同じで機械的に置換しただけで動かすことが可能でした。

# 差分チェック
$ poetry run black           --check --diff  **/*.py

$ poetry run ruff format --check --diff **/*.py

----
# ファイルのフォーマット
$ poetry run black **/*.py

$ poetry run ruff format  **/*.py

ただ、設定でまだ移行出来ないものがあります。

自プロジェクトのblackの設定はあまりカスタマイズせずで設定で使っていました。

[tool.black]
target-version = ["py39"]
line-length = 120
skip-string-normalization = true

ですが、移行を検討開始した当初skip-string-normalization = true に相当する設定がまだ存在しませんでした。 issueは上がっていたのですが、議論が続いていて解決するまでruffへの移行のブロッカーとなっていました。 v0.1.18で quote-style = "preserve" が設定できるようになりました。これが入った事で、自分のプロジェクトではpyproject.tomlとCIの設定変更だけでblackを置き換えることが出来ました。

github.com

docs.astral.sh

ruffに置き換えたことで良かったこととしては、依存関係が減ったのが一つ。それと、パフォーマンスに関してはあんまり改善された実感はありません。自分は poetry run ruff で呼び出しているのでpoetryの処理のオーバーヘッドが体感できない一因かと思います。

ruffは開発のスピードが早いので自分がこのエントリーを数ヶ月放置しているあいだにバージョン0.3までリリースされていました。 2024年はrust製のツールがこれまで以上に流行っていくのでは無いかなと思っております。

java-fakerからdatafakerに移行した

TL;DR

java-fakerのメンテナンスがしばらくされていないのでjava-fakerをforkしたdatafakerに移行した。

What's java-faker?

github.com

Java製のfake data generatorの実装。 rubyのfakerのJavaバージョンという位置づけのライブラリ。

github.com

最終リリースの1.0.2が2020年と1年以上新しいバージョンがリリースされていないことから有志がforkして新たにdatafakerというリポジトリが作成されそこでメンテナンスがされています。

github.com

datafakerの使い方としてはほぼjava-fakerと同じです。

ここにjavafakerを使ったサンプルコードがあります。

import com.github.javafaker.Faker;
import com.github.javafaker.Internet;
import java.util.Locale;

public class FakerApp {
    public static void main(String[] args) {
        Faker faker = new Faker(Locale.US);
        Internet internet = faker.internet();
        for (int i = 0; i < 10; i++) {
            System.out.println(internet.emailAddress());
        }
    }
}

ここからdatafakerへの移行は簡単で、パッケージ名をcom.github.javafaker から net.datafakerに変えるだけです。

import java.util.Locale;
import net.datafaker.Faker;
import net.datafaker.Internet;

public class FakerApp2 {
    public static void main(String[] args) {
        Faker faker = new Faker(Locale.US);
        Internet internet = faker.internet();
        for (int i = 0; i < 10; i++) {
            System.out.println(internet.emailAddress());
        }
    }
}

datafakerは積極的にメンテナンスされていて機能も順調に増えているので手が空いていたら移行をオススメします。

AWS samでQuarkus アプリケーションをデプロイする

What is quarkus?

quarkus.io quarkus.io

Quarkus はJava製の幅広い分散アプリケーションを構築するのに適したフレームワークです。RHELで有名なRedhat 社が中心となって開発を進めています。

Why I wrote this blog post

quarkus.io

上記の通り、Quarkus自身でAWS lambdaを構築する拡張機能とその使い方を提供しているがここにはいくつか課題があります。まず、mvn packageでlambda関数をデプロイするためのAWS samテンプレートを出力してくれるんですがこれをカスタムすることが出来ません。そして、上の方法だと1つのQuarkusアプリケーション=lambda関数しか管理することが出来ないので複数のlambda関数を管理・デプロイすることになると関数の数だけsamのテンプレートを管理するコストが発生することです。

そこで、AWS samもテンプレートをベースに各言語のアプリケーションをビルドすることが出来るのですが、Java 11用に作られたテンプレートがビルドとデプロイは出来るがそのままでは実行出来ないという問題があります。

aws.amazon.com

Lambda関数をQuarkusで作る理由としては、ロギングなどの拡張機能のサポートが充実しているのも1つの理由です。設定を数行追加するだけでAWS Lamda上で実行する際のロギングフォーマットをJSONに変換することが出来ます。

quarkus.io

Create a lambda function using Quarkus with AWS sam

まず、sam initコマンドでlambda関数とsam テンプレートを作成します。

$ sam --version
SAM CLI, version 1.46.0

$ sam init -r java11 -d maven --app-template hello-world  -o . -n sam-hello-lambda

Cloning from https://github.com/aws/aws-sam-cli-app-templates (process may take a moment)

SAM CLI update available (1.48.0); (1.46.0 installed)
To download: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html

次に、quarkusでアプリケーションを作成してHellowWorldFunction以下のファイルを置き換えます。 quarkusコマンドのインストールはこちらを参照してください。

quarkus.io

$ cd sam-hello-lambda 

$ rm -rf HelloWorldFunction

$ quarkus create app --java 11 --maven --extension quarkus-amazon-lambda io.github.yuokada:HelloWorldFunction
-----------
selected extensions:
- io.quarkus:quarkus-amazon-lambda


applying codestarts...
📚  java
🔨  maven
📦  quarkus
📝  config-properties
🔧  dockerfiles
🔧  maven-wrapper
🚀  amazon-lambda-example

-----------
[SUCCESS] ✅  quarkus project has been successfully generated in:
--> /path/to/sam-hello-lambda/HelloWorldFunction
-----------
Navigate into this directory and get started: quarkus dev

そして、次にHelloWorldFunctionの下にMakefileを作成します。これはsam buildコマンドを実行時にbuild-Helloworldfunctionが呼ばれてs3にアップロードされるファイルの中身を生成するのに利用します。 実際のところ、sam packageでここで作成されたLambda関数ごとのディレクトリをzipファイルに固めたものがs3にデプロイされるので、ここではfunction.zipを一度展開しているだけです。

clean:
  ./mvnw clean
build:
  ./mvnw package

build-Helloworldfunction: clean build
  unzip target/function.zip -d $(ARTIFACTS_DIR)/

そして、上で作成したMakefileを利用するようにtemplate.yamlも修正します。重要なポイントは以下の通りです。

  1. Matadataセクションの追加。 see: Building custom runtimes - AWS Serverless Application Model
  2. Handlerの値をio.quarkus.amazon.lambda.runtime.QuarkusStreamHandler::handleRequestに書き換え。これは全てのQuarkusアプリケーションでこの値になります。
  3. Eventsセクションは今回使ってないので削除。
diff --git a/template.yaml b/template.yaml
index 71c9004..a405959 100644
--- a/template.yaml
+++ b/template.yaml
@@ -12,32 +12,24 @@ Globals:

 Resources:
   HelloWorldFunction:
-    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
+    Type: AWS::Serverless::Function
     Properties:
      CodeUri: HelloWorldFunction
-      Handler: helloworld.App::handleRequest
+      Handler: io.quarkus.amazon.lambda.runtime.QuarkusStreamHandler::handleRequest
       Runtime: java11
       Architectures:
         - x86_64
      MemorySize: 256
+      Policies: AWSLambdaBasicExecutionRole
       Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object
-        Variables:
-          PARAM1: VALUE
-          JAVA_TOOL_OPTIONS: -XX:+TieredCompilation -XX:TieredStopAtLevel=1 # More info about tiered compilation https://aws.amazon.com/blogs/compute/optimizing-aws-lambda-function-performance-for-java/
+         Variables:
+           JAVA_TOOL_OPTIONS: -XX:+TieredCompilation -XX:TieredStopAtLevel=1 # More info about tiered compilation https://aws.amazon.com/blogs/compute/optimizing-aws-lambda-function-performance-for-java/
-      Events:
-        HelloWorld:
-          Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
-          Properties:
-            Path: /hello
-            Method: get
+    Metadata:
+      BuildMethod: makefile

ここまで変更を加えれば、後は他のsam製アプリケーションと同様にsam package && sam deployをしてやればアプリケーションを構築出来ます。 (今は、sam deployを呼ぶと暗黙的にsam packageが実行されるみたいですが自分はデプロイ用のテンプレートを出力してそれを使ってsam deployを呼び出したいので明示的にsam packageを呼んでいます。)

最終的に、出来上がったlambda関数のリポジトリがこちらです。 github.com

これで、Quarkusuアプリケーションとそれに付随するリソースを1つのAWS samテンプレートで管理出来るようになりました。

関連リンク

Why I migrated my domain from star domain to Google domains

スタードメイン(旧ネットオウル)を使っていたのだが、 AWS Amplifyで独自ドメインSSL化する過程で""が入ったドメインを入力する必要があって、その際にスタードメインだと""が入ったドメインを入力できないという事が分かりました。

DNS CNAMEレコードに _(アンダーバー)を入力できない https://secure.netowl.jp/bbs/detail.cgi?td=1091

まぁ、"_"を含んだドメインがRFC952に違反するとのことで入力できないのは仕方がないかもしれません。

ホスト名 - Wikipedia https://ja.wikipedia.org/wiki/%E3%83%9B%E3%82%B9%E3%83%88%E5%90%8D

AWS側もそういったドメインレジストラが存在することを想定して"_"を抜いても検証が進められるという仕様になっているようです。

docs.aws.amazon.com

ただ、"_"抜きで設定しても検証がうまく出来なかったのと2013年の状況から9年経って、世の中の変化などに対応する気が無さそうだったので今回移管することとしました。

それに、5月にドメインの登録料の支払いがあったのでその後に移管することになると無駄な支払いになるなと思ってさっさと移行を決めました。

現在、絶賛移管手続き中でGoogle domainsの使い勝手はまだ分からないんですがGoogle domainsでやりたいこと出来なかったら潔く諦めようかなという気持ちです。

新年だしNintendo Switch 有機ELモデルを買った

久しぶりに任天堂のハードウェアを買った。
前回買ったのはNintendo DS (3DSじゃないよ)なので10年以上振りなのかな?

過去2年間、コロナの影響で思うように外出することも出来ずにちょっと運動不足気味だなと感じていて 実際に体重も結構増えてしまい健康診断で色々と言われてしまったので2022年はダイエットをしようかなと思っている。

なんのサポートもなしにダイエットをして1年間続く気がしなかったので続けられるためには何が必要か考えた結果、 ゲーミフィケーション要素があるものが必要だと思いNintendo Switch + リングフィットアドベンチャーという結論に至った。

思い立ったが吉日ということで、年明け早速Nintendo Switch有機ELモデル)を探してヨドバシ.comで購入した。購入前は転売ヤーのせいで直ぐには入手出来ないのかな?と考えてたんだがそんなことはなくて一切待つことはなく購入できてしまった。

調べていくと、Nintendo Switch有機ELモデル)が十二分に供給されているらしく転売ヤーの影響力は全く無いみたいだ。

ここ十数年はPS3,PS4 Pro, PSP, PS Vitaとソニーのハードウェアしか買って来てなかったので、 任天堂ハードのUXがどうなのか未知数の部分が多かったんだけど、switchを起動したら期待以上だった。

まだセットアップとリングフィットアドベンチャーを始めて1日だけswitchが凄く使いやすい。まず、Nintendo Switchの箱に説明書入ってないのにビックリした。説明書なくても問題なく5分程度でセットアップ完了したしこれが最新のUXかーって感心した。リングフィットアドベンチャー用のコントローラーも同じぐらい簡単にセットアップ出来たし全くつまずかなかった。

とりあえず、リングフィットアドベンチャー使って期待通りの結果が得られたらこの約5万円の投資は成功だったと言えるので1年ぐらい継続して結果を残せるように頑張りたい。

HHKBを分解掃除した話

昨年のリモートワーク開始直後にいいキーボードを欲しくなってその当時最新?だったHHKB Professional HYBRID type-sを購入しました。 そこから1年ほど経過してキーボードの隙間にゴミが見えるかなという感じになってきたのでコロナで出掛けられないしキーボードの分解掃除をしてみた。

実は少し前にキーボード掃除用にキートップ引き抜きツールを購入していたのでこれと抜いた1)キートップを入れる箱、2)綿棒、3)ウェットティッシュ, 4)メラミンスポンジを用意して作業した。 メラミンスポンジはダイソーなどの100均で用意出来るはず。 エアダスターがあれば良かったんだろうけど思いつきで始めてしまったので今回は無しで作業した。(無くても汚れの9割がたは落ちるので問題ない)

link: キーボード掃除してますか!?掃除手順と知りたくなかった汚れの実態 | Bauhütte®

初めてのキーボード分解掃除だったが、引き抜きから再配置までトータルで40分ぐらいで完了出来た。慣れてくると30分ぐらいで終われるのかなという感想。 キートップ自体に汚れは目立ってなかったけど分解してみると髪の毛であったり色々とゴミが詰まっていて写真を取ってビフォーアフターを掲載してみようかと思ったけど誰得なので写真は無しです。

抜く前にキーボードの配置を覚えておくの面倒くさいなって人は下のPFUのページをみればちゃんとキーボード配置が分かるのでこれを見て再配置するのが簡単です。

Happy Hacking Keyboard Professional HYBRID 英語配列/白|PFUダイレクト

terraformerを利用してDatadog monitorなどをterraformで管理するようにした

最近、会社の方針でDatadog monitor と SLOのcodificationをしていました。

運用中のシステムであれば既にモニターもSLOもいくつか存在すると思いますが、既存のDatadogリソースを新規でコード化しterraformで作成した新しいモニターで置き換えるのは色々と不都合が生じます。

例えば、既存のモニターに紐付いたリソース、ダウンタイムの設定やドキュメント内のリンクなどがモニターの置き換えによって破壊されます。 リンクがどのモニターと紐付いていたのかはterraform apply時のログなどから調査しないと復旧が困難でしょうし壊れている箇所をすべてリストアップするのは現実的ではありません。

なので、既存のdatadogリソースをterraform importしてかつそれらをコード化する作業が必要になってきます。

数十個のモニターを手作業でインポート&コード化していくのは現実的ではないので何かしらのツールが必要になってくるのですが、自分のケースではterraformerというGoogleCloudPlatformが提供しているツールを利用してcodificationを達成しました。

github.com

なぜ、terraformerかというとDatadogの公式ドキュメントでもこのツールを使ったリソースのimport方法が紹介されており特に不具合がないので紹介されているのだろうという安心感もあります。

docs.datadoghq.com

terraformer はGo製のツールでインストールもhomebrewがサポートしているので特にハマるところはないでしょう。

$ brew info terraformer
terraformer: stable 0.8.15 (bottled), HEAD
CLI tool to generate terraform files from existing infrastructure
https://github.com/GoogleCloudPlatform/terraformer
Not installed
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/terraformer.rb
License: Apache-2.0
==> Dependencies
Build: go ✘
==> Options
--HEAD
        Install HEAD version
==> Analytics
install: 1,537 (30 days), 4,094 (90 days), 12,486 (365 days)
install-on-request: 1,537 (30 days), 4,093 (90 days), 12,481 (365 days)
build-error: 0 (30 days)

$ brew install terraformer

terraformer自体は直接terraformリソースを変更することはなくDatadog関連のリソースにアクセスしてそれをコードに落とし込んでくれます。 なので、Datadogのアプリケーションキーとシークレットキーさえあれば試すことは簡単です。

上述のDatadogのドキュメントだとそれらのキーを引数に取る方法でコマンドを実行していますが、コードを読むと環境変数で取れるようになっているので環境変数を使ってキーをセットするのがオススメです。

$ export DATADOG_API_KEY= YOUR_DATADOG_API_KEY
$ export DATADOG_APP_KEY= YOUR_DATADOG_APP_KEY

https://github.com/GoogleCloudPlatform/terraformer/blob/e00592e28377f32c38b5816dcb13487548ede24a/cmd/provider_cmd_datadog.go#L39-L40

こんな風に複数のタイプのリソースをまとめてコード化出来ます。":" コロン区切りで同タイプの複数のリソースをまとめてコードに落とし込むことも出来ます。

$ terraformer import datadog --resources=monitor,dashboard --filter=monitor=1234,dashboard=abc-def-ghi

# 同タイプのリソースをまとめてコード化する例
$ terraformer import datadog --resources=monitor--filter=monitor=1234:5678:9012

生成されるterraformリソースはDatadogのmessage変数が1行で定義されているので余裕があればヒアドキュメントスタイルに修正しておくのがオススメです。 自分の場合は3桁近いモニターを一度にterraform管理に移行したので面倒くささありそのままにしてしまいました。

Datadogのドキュメントが良く出来ているのでハマることはないと思いますが、コード化した後の微調整が面倒くさくなるのでコード化も良し悪しだなという感じですね。 ブラウザ上で修正することが出来るのでモニターを編集してしまいそれをコードに落とし込まず気づいた人が直すという運用になりがち。