構造体をjsonに変換するツール

作成したツール 今回作成したツールは以下です。 https://github.com/komem3/stout モチベーション 作成したモチベーションとしては、「構造体を適当に定義したけど json の出力が気になる。」、「この構造体に対する json リクエス トをぱっぱと作成したい」という状況と、僕の ast の練習も含めて作成しました。 思ってた以上に面倒な作業でした…。 使用方法 雑に現在の help コマンドの出力は以下のようになっています。 $ stout -h usage: stout -path $struct_path [-no-format] $struct_name options: -path string File path of defined struct. (required) -no-format bool Not format the output json. インストール インストールの仕方は go のツールらしく以下です。 go get github.com/komem3/stout 実例 実際の使い方は以下のように、-path オプションでファイルパスを指定して、その後に対象のオブジェクトを指定して実行を行ないます。 type PtrSamePkg struct { Content string Next string } 上記のようなオブジェクトを持つ define_test.go に対して実行する場合は以下のように実行すると json の出力が得られます。 $ stout -path ./define_test.go PtrSamePkg { "Content": "string", "Next": "string" } おわりに このブログを見る人も少ないと思いますが、よかったら試しに使ってみてもらえると嬉しいです。

2020/11/05(作成日) · 2022/09/26(更新日)

log.Fatalとt.Fatalの違い

どう違うか 結論からいうと、以下のような違いがあります。 log.Fatal: os.Exit(1) を呼び出して強制終了。defer などは呼ばれず、その場でプログラムが終了する。 t.Fatal : runtime.Goexit() を呼び出して終了。defer 処理を行い、その goroutine を終了。 最後に呼び出しているプログラムが違うわけですから、全く違う挙動になるのは当たり前なんですが、いかんせん名前が紛らわしいですよね。。。 詳しい挙動 次にそれぞれの詳しい挙動を確認してきます。 log.Fatal この関数で呼ばれる os.Exit のドキュメントは以下です。 Exit causes the current program to exit with the given status code. Conventionally, code zero indicates success, non-zero an error. The program terminates immediately; deferred functions are not run. For portability, the status code should be in the range [0, 125]. defer も呼ばれないでその場でプログラムを終了すると書いてあります。なので defer などを使わない main 関数ぐらいでしか使いみちがないですね。 一応挙動が分かりやすいように以下のようなコードを書いてみました。 package main import ( "log" ) func main() { defer log....

2020/10/15(作成日) · 2022/09/26(更新日)

型付nilについて

はじめに 今回は go 言語の型付 nil の直感的でない挙動について説明します。 まずは、次のコードを実行してみてください。 playground package main import "fmt" func main() { var x *int var y *int = nil var z error fmt.Printf("x -> %#10v; x is nil -> %v\n", x, x == nil) fmt.Printf("y -> %#10v; y is nil -> %v\n", y, y == nil) fmt.Printf("z -> %#10v; z is nil -> %v\n", z, z == nil) fmt.Printf("x isNil -> %v\n", isNil("x", x)) fmt.Printf("y isNil -> %v\n", isNil("y", y)) fmt....

2020/09/28(作成日) · 2022/09/26(更新日)

zap + stackdriver logging + grpc on Cloud Run

目標 grpc 使用時に、zap の出力結果が stackdriver logging でまとまるようにしていきます。 cloud run での出力条件 Cloud run の標準出力はデフォルトで logging にエクスポートされます。しかし、特定の出力は特殊フィールドとみなされます。まずは、その特殊フィールドを見ていきます。 公式ドキュメントには以下のように記載されています。 When the Logging agent receives a structured log record, it treats the following fields specially, allowing you to set specific fields in the LogEntry object that get written to the Logging API. つまり、jsonなどで出力された際に、特定の名前のフィールドが特殊フィールドと扱われることが分かります。 一個ずつ特殊フィールドを見ても公式をなぞるだけなので、今回目指したい出力を以下に記します。 { "severity": "ログの重要度(例:DEBUG)", "message": "ログメッセージ", "time": "ログのタイムスタンプ", "logging.googleapis.com/trace": "トレースID(例:projects/[PROJECT-ID]/traces/[V])", "logging.googleapis.com/spanId": "同一トレース内のスパンID(例:000ddfff3)" } 上記のようなフィールドが特殊フィールドとみなされ、標準で出力されるリクエストのログに対してまとまってくれます。それではこれを目指して行きます。logging.googleapis.com/trace_sampled はopencensusなどのtraceライブラリの設定が必要なので、今回はやりません。 zap で出力する zap の設定 上記のように出力するために、zap の設定は以下のようにしました。今回はプラグインなどを使わず自力で実装しています。...

2020/08/12(作成日) · 2022/09/26(更新日)

fgprofについて

fgprof とは fgprofとは、go 言語のサンプリングプロファイルツールとなります。 プロファイルツールって何ぞやって人もいると思いますが、簡単にいうと「処理にかかった時間やメモリの使用量を測定するツール」といった感じになります。使用してみると下の図のように、処理に対して、どの関数がどのくらい時間がどのくらいかかったのかを、視覚的に見ることができます。(下の図は fgprof に記載されている pprof のサンプル図です。) gcp だと stack trace とかをイメージしてもらうのがいいですね。 そして、go 言語には、すでに pprof という公式のプロファイルツールが存在します。しかし、この pprof は on-cpu の処理のみ測定が行うわれます。on-cpu の処理というのはいわゆる cpu 上の計算のみです。このため、DB に対してのクエリ、他サービスへのアクセス、ディスク IO などの、cpu 上で行われない処理は計算されません。そのため、pprof を使うと真のボトルネックとなる処理が分からないことが多々有りました。 そこを改良したのが fgprof となります。fgprof を使うことで cpu 上で行われない処理(off-cpu)の処理を測定し、真のボトルネックを見つけることが可能になりました。すごいツールです。 使用例 go-chi で以下のようなサーバーを作成して、どのようにプロファイルされるかを見ていきます。 package main import ( "context" "net/http" "github.com/go-chi/chi" ) func main() { r := chi.NewRouter() r.Get("/", func(w http.ResponseWriter, r *http.Request) { // cpuを止める処理 cpuIntensiveTask() // 良くわからない関数 weirdFunction() // なんらかの network request slowNetworkRequest(r.Context()) }) panic(http....

2020/08/04(作成日) · 2022/09/26(更新日)

git で日記を管理したい

要約 git で日記をいい感じに管理したいという思いを込めて日記管理用の cli ツールを作成いたしました。 https://github.com/komem3/go-diary 背景 バージョン管理やリモートリポジトリを使って日記・日報を管理したいという思いが有りましたが、いかんせんディレクトリが汚くなってしまうのが問題でした。定期的にディレクトリを綺麗に整理する根気があれば良いのですが、三日坊主になりやすい私なんかはそれだけで日記を書くのが嫌になってしまいます。 そこで、日記のファイルをいい感じのディレクトリ構造で管理するツールを作成することに。 インストール go で作成したツールのため、以下のようにダウンロードします。 $ go get github.com/komem3/go-diary/cmd/diary 使い方 $ diary -h Diary is a CLI libray for managing your diary. This application can format your diary directory, and make index file. Usage: diary [command] Available Commands: format Format directory help Help about any command init Initialize directory new Generate new diary Flags: -h, --help help for diary -v, --version version for diary Use "diary [command] --help" for more information about a command....

2020/07/22(作成日) · 2022/09/26(更新日)