Upgrade to Pro — share decks privately, control downloads, hide ads and more …

TinyGoでオブザーバビリティ?OpenTelemetryはTinyGoで使えるのか / I...

Avatar for ymotongpoo ymotongpoo
October 10, 2026

TinyGoでオブザーバビリティ?OpenTelemetryはTinyGoで使えるのか / Is OpenTelemetry available in TinyGo environment?

TinyGo Conference 2026における登壇資料です。
https://conf.tinygo-keeb.org/2026/

検証をした結果の調査資料はこちらにあります。
https://zenn.dev/ymotongpoo/books/tinygo-otel-esp32

PoCはこちらです。
https://github.com/ymotongpoo/tinygo-otel-esp32

Avatar for ymotongpoo

ymotongpoo

October 10, 2026

More Decks by ymotongpoo

Other Decks in Technology

Transcript

  1. "In general, the OTel spec is not designed for the

    limited resources present in embedded systems."​ (一般に、​OTelの​仕様は​組み込みシステムに​ある​限られ た​リソースに​合わせて​設計されていません) Ted Young​(OpenTelemetry共同創設者)、​open-telemetry/community#2160、​2024年6月
  2. ビルドしてみる SDKと​エクスポーターは​ビルドで​止まる APIは​記録の​呼び出し口、​SDKは​APIの​実装で​値の​集計と​属性の​付与を​担う。 エクスポーターは​SDKが集 ​ めた値 ​ を​OTLPで送 ​ る部

    ​ 品。 構成​(OpenTelemetry Go v1.46.0)​ 結果​ 止まった​箇所 otel/metric と metric/noop (APIだけ)​ 成功​(6,400バイト)​ なし otel/sdk/metric を​追加 失敗 sdk/resource から x/sys/unix otlpmetrichttp を​追加 失敗 envconfig の tls.X509KeyPair APIにだけ依存する​ライブラリなら、​TinyGoの​プログラムに​組み込んでも​ビルドは​通る
  3. 原因 止まる​理由は​メモリではなかった # sdk/metric を追加したビルド system calls are not supported:

    target emulates a linux/arm system on xtensa # otlpmetrichttp を追加したビルド .../[email protected]/internal/envconfig/envconfig.go:143:19: undefined: tls.X509KeyPair 部品 前提に​している​こと​ SDK( sdk/resource )​ OSに​問い合わせて​ホストの​情報を​集められる​ エクスポーター​( envconfig )​ 証明書を​扱える​完全な crypto/tls が​ある​
  4. PROTOBUF ビルドが​通っても​実機で​panicする 生成型を proto.Marshal に​渡すと​最初の​送信 で​落ちる wifi connected, address: 192.168.0.102

    panic: unimplemented: (reflect.Type).MethodByName() abort called 公式の​対応表では reflect は​importableも​ passes testsも​yes importできる​ことと、​個別の​メソッドが​実装 されているこ ​ とは別 ​
  5. エンコ ー ド OTLP/JSONは​構造体の​タグで​書ける type span struct { TraceID string

    `json:"traceId"` SpanID string `json:"spanId"` ParentSpanID string `json:"parentSpanId,omitempty"` Name string `json:"name"` Kind int `json:"kind"` } OTLPの​仕様が​定める​正式な​エンコーディング で、​Collectorは​protobufと​同じく​受け付ける IDは​16進の​文字列、​64ビット整数は​10進の​文字 列、列 ​ 挙値は整 ​ 数 10タイムシリーズで​3,016バイト​(protobufは​ 1,379バイト)
  6. HTTPクライアント 脱 net/http で​フラッシュ使用量が​30%減る Wi-Fi接続、​時刻同期、​3シグナルの​送信を​含むファームウェア全体で​比較 項目​(バイト)​ net/http 手​書き 差 フラッシュ​(​プログラムの​格納先)​

    1,067,175 748,691 318,484 静的RAM 147,636 114,796 32,840 差は crypto/tls と、​そこから​付いてくる crypto/x509 や math/big の​分 平文しか​話さない​デバイスでは​一度も​実行されない
  7. 時刻 NTPの​実装は​あるが​呼べる​APIが​無い 時刻が​1970年の​ままだと、​データは​Grafanaの​表示範囲に​入らない # espradioの公開APIで接続しただけ warning: clock never synchronised; timestamps

    will be wrong clock ready: 1970-01-01 00:00:33.0411515 +0000 UTC # SNTPを自分で書いたあと sntp: resolved pool.ntp.org to 167.179.119.205 sntp: clock set to 2026-09-15 06:33:52.876544886 +0000 UTC lneto は​NTPを​実装しているが、​espradio v0.3.0の​接続手順からは​呼べない UDPで​48バイトを​送る​SNTPを​自分で​書いた
  8. スタック スタック不足の​エラーが​出ない​こともある 結果​ -stack-size 8KB​(デフォルト)​ EXCCAUSE = 28 (LoadProhibited) で​落ちる​

    12KB EXCCAUSE = 28 (LoadProhibited) で​落ちる​ 14KB fatal error: goroutine stack overflow で​落ちる​ 15KB 動く​ 16KB 動く。​30分の​連続稼働を​通過 encoding/json は​入れ子の​OTLPを​再帰で​たどる。​12KB以下では、​スタック不足の​報告より​先 に​メモリが​破損する
  9. 3つの​シ グナル デバイスの​外から​測れない​ことだけを​送る メトリクスは​10秒ごと。​ログと​トレースは​メトリクスの​送信が​成功した​直後に​送る メトリクス ログ トレース Goの​ヒープ Wi-Fiドライバの​メモリ 電波強度(

    ​ RSSI)と送 ​ 信の​結果 起動、​送信の​失敗、​回復、 周期全体の​スパンの​下に 16件を​超えたら​古い順に​上書き その件 ​ 数はメ ​ トリクスで送 ​ る POSTの​子スパン 12本の​タイムシリーズ 4種類の​出来事 部分的な​拒否 送信1周期 値の​読み取り、​エンコード、
  10. 連続稼働試験 30分の​連続稼働で​送信の​失敗は​0回 送信間隔10秒、​スタック16KB。​15分の​時点で​Collectorを​再起動 メトリクスのみ​ 3シグナル 送信 180回 180回 失敗 0回

    0回 800バイト 2,992バイト 1回 7回 178,704バイト 203,776〜206,128バイト 6.1秒 9.1秒 項目 1回の​送信で​増える​ヒープ GC GC後の​ヒープ 再​起動からの​回復 GC後の​ヒープは​増え続けず、​Collectorの​再起動後も​次の​周期で​送信が​再開する
  11. 役 割 の ​分 担 TLSと​属性の​付与は​Collectorに​任せる デバイス その​場でしか​測れない​値を​測る 時刻を​合わせる バッファに​上限を​置き、​溢れた​件数を​送る

    一時的な​失敗​(429、​502、​503、​504)も​ 送り直さず、​次の​周期に​新しい​値を​送る Collector 環境の​属性を​足す deployment.environment.name など TLSと​認証情報を​持つ データをま ​ とめ、バ ​ ックエンドへ​再送する
  12. 結論 まとめ OTel Go SDKが​使えない​原因は、​メモリ制限ではなく​ホストOSへの​依存と reflect の​未実装 OTLPの​スキーマは​使える。 encoding/json 、​手書きの​HTTPクライアント、​SNTPで​話せる

    マイコンで詰 ​ まるのはメ ​ モリの量 ​ より、送 ​ 信ごとのメ ​ モリ確保と​goroutineのス ​ タック デバイスはそ ​ こでしか分 ​ からないこ ​ とだけを送 ​ り、​TLSと属 ​ 性の付 ​ 与は​Collectorに任 ​ せる Collectorから先 ​ は、サ ​ ーバーで使 ​ う​OpenTelemetryと同 ​ じパ ​ イプライン PoCは​これです https://github.com/ymotongpoo/tinygo-otel-esp32
  13. 報告した​I SSUE 調査で​見つけた​問題を​tinygo-orgへ​報告した issue 内容 espradio#75 接続手順から​時刻を​合わせる​手段が​無い​ espradio#76 接続中の​アクセスポイントの​RSSIを​返す関数の​提案 tinygo#5839

    ESP32-S3で​スタックの​あふれが​報告されない​ tinygo#5204へ​追記 tls.X509KeyPair が​無く otlpmetrichttp を​ビルドできない​ tinygo#3862へ​追記 MethodByName が​未実装で proto.Marshal が​panicする​ 2026年10月7日に​報告。​上の​3件は​新規の​issue、​下の​2件は​既存の​issueへの​コメント