地方エンジニアの学習日記

興味ある技術の雑なメモだったりを書いてくブログ。たまに日記とガジェット紹介。

【Go】otelでspanにattributeを付ける

SetAttributesを使うことで実現できる。例えば以下はtraceの情報にAddという関数の引数をattributeにつけることで情報が追加される。

package calc

import (
    "context"

    "go.opentelemetry.io/otel"
    "go.opentelemetry.io/otel/attribute"
)

var tracer = otel.Tracer("otel-echo-calc")

func Add(ctx context.Context, x, y int) int {
    ctx, span := tracer.Start(ctx, "Add")
    defer span.End()
    span.SetAttributes(
        attribute.Int("x", x),
        attribute.Int("y", y),
    )

    return x + y
}

エラーを記録する

span.RecordErrorを使うことでエラーを記録することができる。またspan.RecordError(err, trace.WithStackTrace(true))とすることでスタックトレースまで送ることができるようになっている。ただこれをやるとデータ量が嵩みそうなので使い所はきちんと選んで使う感じになりそう

pkg.go.dev

jqでlessして色をつけたい

lessに-Rをつけて

       -R or --RAW-CONTROL-CHARS
              Like -r, but only ANSI "color" escape sequences and OSC 8 hyperlink sequences are output in "raw" form.  Unlike -r, the screen appearance is
              maintained correctly, provided that there are no escape sequences in the file other than these types of escape sequences.  Color escape sequences are
              only supported when the color is changed within one line, not across lines.  In other words, the beginning of each line is assumed to be normal (non-
              colored), regardless of any escape sequences in previous lines.  For the purpose of keeping track of screen appearance, these escape sequences are
              assumed to not move the cursor.

jqには-Cをつければ良い

-C               colorize JSON;

LESSという環境変数にオプションを入れておけばlessの方は反映されるのでやっておくだけでも良い

$ export LESS='-R'

サービス稼働中にMySQLのプライマリDBがメジャーアップデートされたらどうなるのか

考えただけでも恐ろしいが考えてみる。どれくらいのダウンがありそうだろうか。ざっと考えると1~4までは大体決まった作業になりそう。ただ問題は5でこれを焦りながらやるのはメンタルやられそうだなぁと思った。いやーそうならないようにしよう。

1. シャットダウン処理

dev.mysql.com

永続化処理とかをしたりする。buffer poolが大きければまあ時間がかかる

2. アップデート処理

バイナリの置き換えやmysql_upgradeを打ったりする。システムテーブルのアップグレードやインデックスの再構築、テーブルチェックをしたりする。

dev.mysql.com

3. 起動処理

buffer poolを復元したりで時間がかかる。innodb_buffer_pool_dump_pctとかを設定しておけばある程度はコントロールできる。

dev.mysql.com

4. 暖機

buffer poolを復元したとしてもそれは終了処理の時の内容なのでサービス特性に合わせた形で暖機が必要だったりするのでそれをやる

kikai.hatenablog.jp

5. エラー対応

クライアントがそのままアップデート後のMySQLに対応していれば良いがそうではない場合もある。その時は地道にエラーを消していく必要がある。事前にアップデートに関する情報を調べておければ良いがそれすらもしてない場合はとても大変なことになりそう。

感想

大変だ

【Go】GOOS=wasip1でビルドしたwasmでTCPサーバを起動する

github.com

wasip1ではネットワーク関連の機能が一部しかサポートされてないので使えないと思っていたがstealthrocket/netを使うことでできる模様。

こんな感じのDockerfileを用意しておく。このライブラリではWasmEdgeをサポートしているらしいのでそちらをインストール

FROM golang:1.21.4-bookworm
RUN curl -sSf https://raw.githubusercontent.com/WasmEdge/WasmEdge/master/utils/install.sh | bash
COPY main.wasm /main.wasm

あとはGoでhttpサーバを動かす際にライブラリを指定することで実行できるようになっている。ライブラリではWASI環境でソケット操作を行うための関数群を定義されていてそちらを通してWASMランタイムの機能を呼び出してソケット操作をすることで実現しているようです。

package main

import (
    "net/http"

    "github.com/stealthrocket/net/wasip1"
)

func main() {
    listener, err := wasip1.Listen("tcp", "127.0.0.1:3000")
    if err != nil {
        panic(err)
    }

    server := &http.Server{
        Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            w.Write([]byte("Hello, World!"))
            w.WriteHeader(http.StatusOK)
        }),
    }

    if err := server.Serve(listener); err != nil {
        panic(err)
    }
}

中身を見る

listenの先を見るとこんな実装がされています。sock_listen()を呼び出してerrnoをチェックしています。

func listen(fd int, backlog int) error {
    if errno := sock_listen(int32(fd), int32(backlog)); errno != 0 {
        return errno
    }
    return nil
}

sock_listen()は以下のような実装になっていました。go:wasmimport wasi_snapshot_preview1 sock_listenはWASMモジュール内でWASIのwasi_snapshot_preview1モジュールからsock_listenをインポートするように指示しています。

//go:wasmimport wasi_snapshot_preview1 sock_listen
//go:noescape
func sock_listen(fd int32, backlog int32) syscall.Errno