雑記帳

ちょっとした文章とかメモ書きとか。

Fluentd実践入門を読み終えた

昨年にFluentd実践入門を@tagomorisさんに献本いただいていたのですが、色々とバタバタしていたこともあり、ようやく読み終えました。

Fluentdを使い始める方にも使ってみたけれど、プラグインの機能が足りず痒い所に手が届かないけれどどのように拡張したら良いかわからない・・・。と言う初級者にも中級者にも刺さる書籍となっていました。Fluentdを開発していてもBufferありのアウトプットプラグイン(Buffered Output Plugin)のチューニングの仕方とかコードだけ追っていても若干怪しいことがあるので、大変参考になりました。

いくつかの章はクリアコードの社員としてメンテナンスをしていた時に特に力を入れて開発していた機能の紹介もあり、懐かしみながら読めました。

TLSに関係するところではcert_logical_store_nameと言う私が開発しました、そしてそのためにC拡張も作成しました。と言う思い出深いパラメータを見ることができました。

Fluentdのこれから

Fluentdはバラバラになっていたログ収集を統一的に扱えるログエージェントとして登場しました。しかし、Fluentdはログを統一的に取り扱うログエージェントであり、クラウドネイティブなソフトウェアを扱う開発者はログだけではなく、ノードやコンテナの健全性もログと同時に取り扱い収集するObservabilityと言う新しい概念をエージェントに取り入れ始めています。

「オブザーバビリティ(可観測性)」とは「Observe(観察する)」と「ability(能力)」を組み合わせであり、観察する能力という意味の「Observability(可観測性)」として訳されます。

つまり、オブザーバビリティとは従来に比べてシステムを観察する能力をより高めた監視体制のことです。

https://ops.jig-saw.com/tech-cate/observability

Fluent BitはFluentd傘下のプロジェクトとして出発しています。ログに限らずPrometheus互換のメトリクスを扱えるnode_exporter_metrics, windows_exporter_metricsのようなノードの健全性をメトリクスを通じて収集するメトリクスエージェントだけでなく、OpenTelemetryと言うObservabilityの走りとなるテレメトリーの集約・送信もサポートしています。

また、Fluent BitはWebAssemblyによるフィルタープラグインを書くことも可能となっています。

このようにFluent BitはIoTやObservabilityの文脈においてエッジプラットフォームを目指すエージェントとしての開発が進められています。

このことからFluentdに関しても内部のメトリクスをプラグイン化して内部で扱うだけでなく、例えば、他のメトリクスプラグインで内部メトリクスをPrometheus互換で処理可能にするメトリクスプラグイン機能を入れてみてあります。しかし今のところ、Fluentdのコア開発チームは今ところ安定性や未解決になっている問題の解決に関心があるようです。

おわりに

まだまだFluentdでサポートしなければならない機能はあると思います。Fluentdではメトリクスやトレースを扱うのには小回りが効かないところもあるのですが、Fluentd実践入門を読めば一通りのログ集約周りの設計のヒントが散りばめられており、Fluentdのソースコードを読み込んで使っている方でも新たな発見があるかもしれません。
この書籍がなかった時代から手探りで開発してコミュニティと関わってきた身からすると隔世の感があります。

RISC-V 64bitのボードを手に入れた

昨年末kickstarterにてStarfiveTech Vision Five 2というriscv64のアーキテクチャのボードのプロジェクトが立っていたので、プレッジしてみた。

Super early birdにて8GB WiFiなしのボードを選択していた。

存在を忘れつついたが、昨年の暮れに発送連絡なしに着弾していた。

最新のDebianイメージはImage-69となる。そのままではU-Bootのバージョンが古いらしく、起動できない。
GPIO 24pin経由でtftpサーバーを使いつつ、U-Bootとfirmwareのアップデートを行うと、Debian 12 Bookwarmのイメージが起動する。

このイメージはNVMeのサポートが有効化されているため、M.2の端子にMVNeのSSDを挿すと認識される。

# apt install -y pciutils
# lspci
0000:00:00.0 PCI bridge: PLDA XpressRich-AXI Ref Design (rev 02)
0000:01:00.0 USB controller: VIA Technologies, Inc. VL805/806 xHCI USB 3.0 Controller (rev 01)
0001:00:00.0 PCI bridge: PLDA XpressRich-AXI Ref Design (rev 02)
0001:01:00.0 Non-Volatile memory controller: KIOXIA Corporation Device 0008 (rev 01)

M.2 SSDはKIOXIAのものを使用した。ext4ファイルシステムとしてフォーマットしている。

# uname -a
# Linux starfive 5.15.0-starfive #1 SMP Mon Dec 19 07:56:37 EST 2022 riscv64 GNU/Linux

LinuxカーネルはRISC-V 64bitとして動作している。ただし、このカーネルではIPv6が有効化されていない。

root@starfive:~# cat /boot/boot/config-5.15.0-starfive | grep IPV6
# CONFIG_IPV6 is not set

RISC-Vのツールチェインはだいぶ揃っていて、gccはおろか、cmakeやその他各種ライブラリやツールチェインは一通り揃っている。もちろん、gitもaptからインストールすれば何事もなかったかのように動作する。

RISC-Vではハードウェアにベッタリなアセンブラに頼っているアプリケーションは動作しないが、そうではないものは一通り動作する。LuaJITについてはRISC-V 64bit(riscv64)のサポートはまだ入っておらず、動作しない

では、wasm-micro-runtime(WAMR)についてはどうかというと、これにはサポートが入っている。ただし、逐次翻訳の方にはまだ問題があり、動作しない。WAMR-1.1.1で確認。Ahead Of Time (AOT)コンパイルしてしまえば、問題ない。

error: WASM module load failed: pre-compiled label offset out of range

AOTコンパイルを行えば動作するため、RISC-VではStarfiveのボードが出るまで非力な環境しかなく、手が回っていないのかもしれない。

M1 Macを開発環境に使ってみることにした

Macbook Pro M1のリファービッシュ品が購入できたので、darwin-arm64環境が手に入った。

Docker Desktop For Apple Siliconについてはすんなりインストールもでき、docker pull をするとarm64v8なDockerイメージが落ちてくる。嬉しい誤算だったのは、arm64のLinuxパッケージをdockerを使ってビルドすると、qemuを使ってビルドしていたx86_64環境の5〜6倍速でパッケージがビルドできるところ。2〜3時間掛かっていたのが15分弱くらいになる。

社内の自分が関わっているDocker imageに関してはGitHub ActionsでBuildKit(buildx)を使うように変更したので、multi-archなDockerイメージにできているので、docker pullをすると無難にarm64v8なイメージがpullできる。例)https://github.com/calyptia/calyptia-fluentd-docker-image/pkgs/container/fluentd

homebrewはM1に対応したarm64バイナリーが降ってくるし、javaはopenjdkをhomebrewからインストールされば何事もなく使用できる。

macOSのラップトップではBootCampを使っていなかったので、これに関しては何も障害にはならなかった。アクティビティモニタで見るとほとんどアーキテクチャがAppleになっていた。

OneDriveだけはまだRosetta2で動いているようで、アーキテクチャにIntelの文字が躍る。

Apple M1でないとdarwin-arm64環境の動作ができなかったので、apple M1対応パッケージのビルドができていなかったが、これについてもほぼすんなりと対応できた。OpenSSLのビルド時に darwin64-arm64-ccno-asm フラグが必要になった。これだけが注意点だった。

M1 Macは出始めこそ色々と躓くポイントがあったが、ほぼ解消されている印象で動作音も静かで、しかもパワフルという印象になった。

英語ミーティングの対処方法

英語ミーティングの機会がなんだかんだで年々増えているので、自分なりの対処方法をまとめてみます。
この記事を書いている本人はある程度読み書きができて、多少なりとも英語を話すことができるようになったというレベル感です。

英語を話すときに気をつけていること

英語ミーティングに慣れようと英語ミーティングの他にオンライン英会話を週一でやってみていますがネイティブの講師の先生曰く、ネイティブがうまいと感じる英語と、非ネイティブがうまいと感じる英語には差があるのだそうです。

その先生の基本スタンスは英語はコミュニケーションツールなのでうまく見せるよりもちゃんと伝わることを意識して話すようにしなさい、とのことです。

  1. 話すときは早すぎず一定のペースで
  2. 英単語はシラブルを壊さないように発音する
  3. 文末まではっきりと発音する

実際にこの3つの要件を聞いたときになるほど、と思いました。

1はよく英語が上手いと周りに認めさせる人がやりがち?なんでしょうか。ネイティブの先生でも早口は聞き取りにくいそうなので、伝わる英語を話すなら一定のペースを心がけると良さそう。

2は個人的には割と気をつけている方で、そこまでネイティブの先生には聞き返されないし、英語ミーティングをしていても発音で聞き返されることは少ないです。(非ネイティブではないので見逃されているという可能性はなきにしもあらず)

3はモゴモゴ喋る人ならやりがちなので気をつけないといけません。よく文末まで一定のトーンで話していないことがあるので気をつけたい。

実際に発音に気をつけているところ

辞書を見れば発音記号は載っているので、発音記号通りに発音すればネイティブの耳に優しくなるかというとどうもそうでもないようです。

例えば、necessityという単語はne/ces/si/tyとsの子音が複数のシラブルに跨り、このss音の近辺に強勢が置かれます。(発音してみてー、と言われて、necessityとネを強調したり、neのe音をはっきりを発音したら違うよーと即座に訂正されました。。。)

色々と発音を試してみたところ、強調したくない母音はシュワ(schwa)で発音するとほぼ確実にアクセントを置いていないように聞こえるようでした。
発音記号で書くと / nəˈsɛs ɪ ti / という発音です。
necessityの下線を引っ張ったeは弱い母音として発音したらやっとOKが出ました。

まとめ

ネイティブの講師の先生に曖昧な母音で〜はっきりしていなくて〜云々っていうのがシュワなんだ、と言っても詳しく解説しているページのURLを使って説明しないと通じませんでした。
(それを言うと、日本語話者は母音の無声化を頻繁に使っていますが、意識しないとそんな現象が起きていると言うのに気づかない、と言うのと同じ感じのようです)

なるべくシラブルを壊さないというのと、誤った位置の母音にアクセントを置かれていないようにするために、シュワの練習をした方がいいんじゃないかと思いました。

よくあるrとlの区別をつけようとか、vとbの区別をつけようとかthの発音を頑張ろうとかいうのは何回も耳にしていると思うので、深くはつっこみませんでした。

Linux環境のオーディオI/Fを刷新した

在宅勤務になって以降、メイン作業PCはLinuxデスクトップ、Windowsラップトップ、MacBook Pro 2016を行ったり来たりしている。

LinuxでZOOMやGoogle MEETを使ってウェブミーティングをすることがメインになったため、何年も前に買っていたNative InstrumentのKomplete 6を48Vのファンタム電源付きのオーディオI/Fとして使っていた。

マイクにはコンデンサータイプのマランツMPM-1000を使用しているため、48Vのファンタム電源が必要だった。

Komplete 6自体はオーディオI/Fとして優れているシロモノで、これ自体でも特に不満がなかったが、ファンタム電源経由でのマイク入力がGAINを掛けてもZOOMでは十分なマイク入力音量にならず少し困っていた。

USB接続でファンタム電源ありのオーディオI/Fを探してみたところ、Steinberg UR22 mkIIが良さそうだったので、これをチョイスしてみた。

Ubuntu Linux 18.04.5 LTSに接続しても普通に認識して使えた。

[ 1.879093] usb 1-5.1: New USB device found, idVendor=0499, idProduct=170f
[ 1.879094] usb 1-5.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 1.879095] usb 1-5.1: Product: Steinberg UR22mkII
[ 1.879096] usb 1-5.1: Manufacturer: Yamaha Corporation

Steinbergが出しているUR22 mkIIというオーディオI/Fなのに製造元はYamahaという表示になるようで。

結果としては、この選択は大正解でマイクも大幅にGAINを掛けてもノイズがほぼ乗らないし、
心なしかイヤホン出力も音質が上がった気がする。

NVR510でBiglobeのMap-E接続を試みる

インターネットを快適するにはルーターもいいやつを選びたいよね、と言う記事です。

在宅ワークに移行してました。

在宅ワークを行うと、固定回線を日中に多く使うようになってしまいました。元々固定回線に使っていたルーターはBuffaloのWXR-1900HP3です。ただし、このルーターは数日に一回再起動をしないと無線が繋がらなくなる不具合があり、困っていました。

不具合の症状から見るに、このルーターはLinuxが動いてるのでメモリが足りなくなってOOM Killerが発動してるんじゃないかなと思っているところ。

流石になんとかしたいと言うことで、NVR510を導入してみました。前にヤマハの中古ルーターをいじっていたこともあって親切さ加減が進化していて感動です。

NVR510はヤマハが出している小規模オフィスのネットワークにも耐えうる製品です。市販のコンシューマー向けルーターではIPoE IPv6接続をしつつ、PPPoE IPv4接続も維持すると言う使い方ができる製品はなかなかないですが、このNVR510は設定を手で書いてやることでIPoEとPPPoE接続のセッションを同時に張れます。

NVR510を設定する

NVR510の管理画面には簡単設定があり、IPoE接続でもPPPoE接続でもマウスぽちぽちで終わりじゃーい!と意気揚々と設定したらそんなことはなかった😅。

IPoEでの接続はMap-EやDS-Lite接続と色々種類があるらしく、プロバイダーが独自でVNEを構築している場合があるそう。

DS-Lite: https://www.geekpage.jp/blog/?id=2019-7-24-1

Map-E: https://aero-ship.net/2019/01/difference-bw-mape-dslite/#MAP-EV6

調べたところ、BiglobeのIPv6 OptionはMap-E接続で行われ、IPv6の設備はJPNEではなく自前で運用しているとのこと。

NVR510のIPoEの機能の説明を見ると、JPNE(日本ネットワークイネイブラー株式会社)以外のIPoE接続は自前で設定を書く必要があるらしい。

日本ネットワークイネイブラー株式会社が提供する「v6プラス」を利用してインターネット接続をする機能を提供します。

http://www.rtpro.yamaha.co.jp/RT/docs/v6plus/index.html

どうりで、IPoE接続を簡単接続から設定しても繋がらないわけです😇。

NVR510でBiglobeのMap-E接続の設定を書く

設定を書くと言ったが、全て手でやるとは言っていない。

NVR510のファームウェアのバージョンはRev.15.01.16 (Wed Mar 11 12:06:39 2020)です。

NVR510のコンソールにログインして

> show ipv6 address 
LAN1 scope-id 1 [up]
Received: 121300 packets 20992758 octets
Transmitted: 93152 packets 12673027 octets

global [global IPv6 address] (lifetime: 604621/2591821)

[global IPv6 Address]をhttp://ipv4.web.fc2.com/map-e.html でIPv6 プレフィックスかアドレスを入力:のフォームに入力すればCE IPv6 アドレス(ceipv6addr)、IPv4アドレス(outeripv4)、ポート番号(portrange)が埋まるはず。この出力する設定は光電話は使っていません。

# ref: http://ipv4.web.fc2.com/map-e.html
# v6plus ref: https://api.enabler.ne.jp/6a4a89a8639b7546793041643f5da608/get_rules?callback=v6plus

ceipv6addr = "[CE IPv6 Address]"
eastbraddr = "2001:260:700:1::1:275" # for east-flets
outeripv4 = "[Outer IPv4 address]"
portranges = "[IPv4 port range]"
ports = portranges.split(' ')
config = <<-EOC
# ---- IPv6 configuration ----
ipv6 routing on
ipv6 prefix 1 ra-prefix@lan2::/64

description lan1 LAN
ipv6 lan1 address ra-prefix@lan2::1/64
ipv6 lan1 rtadv send 1 o_flag=on
ipv6 lan1 dhcp service server

description lan2 "Biglobe FTTH IPoE"
# CE IPv6 address #{ceipv6addr}
ipv6 lan2 address #{ceipv6addr}/64
ipv6 lan2 mtu 1500
# ipv6 lan secure filter in part
# ipv6 lan secure filter out part
ipv6 lan2 dhcp service client ir=on

# IPv4 related
ip route default gateway tunnel 1
  description tunnel MAP-E
  tunnel select 1
  tunnel encapsulation ipip
  tunnel endpoint address #{ceipv6addr} #{eastbraddr}
  ip tunnel mtu 1460
  ip tunnel nat descriptor 1010 1011 1012 1013
  tunnel enable 1

# NAT table for IPv6 tunnel - 1
nat descriptor type 1010 masquerade
nat descriptor address outer 1010 #{outeripv4}
nat descriptor address inner 1010 auto

# NAT table for IPv6 tunnel - 2
nat descriptor type 1011 masquerade
nat descriptor address outer 1011 #{outeripv4}
nat descriptor address inner 1011 auto

# NAT table for IPv6 tunnel - 3
nat descriptor type 1012 masquerade
nat descriptor address outer 1012 #{outeripv4}
nat descriptor address inner 1012 auto

# NAT table for IPv6 tunnel - 4
nat descriptor type 1013 masquerade
nat descriptor address outer 1013 #{outeripv4}
nat descriptor address inner 1013 auto

nat descriptor masquerade port range 1010 #{ports[0..3].join(' ')}
nat descriptor masquerade port range 1011 #{ports[4..7].join(' ')}
nat descriptor masquerade port range 1012 #{ports[8..11].join(' ')}
nat descriptor masquerade port range 1013 #{ports[12..15].join(' ')}

# Some filtering configurations...
EOC

print config

このコードはGitHubにもおいてあります。

https://github.com/cosmo0920/dotfiles/blob/master/piece-of-biglobe-map-e-configuration/ipoe.rb


map-e.rbのようなファイルに保存してruby map-e.rbのように実行すると、標準出力に最終的なIPv6に関係する設定片が出力されます。

NVR510の設定ファイルは https://blog.hiros.info/2018/06/biglobeipv4-over-ipv6-rtx830.html を参考に作成しました。

結果

速度が出て、回線が安定するようになったみたいです。

fluent-bit 0.2.0 available in Homebrew now

Today, fluent-bit, which is a Data Collector for IoT, formula has been merged into Homebrew master.

You can install fluent-bit like this:

$ brew install fluent-bit

For now, fluent-bit 0.2.0 will be installed in your OS X.

Or, try to install development version:

$ brew install fluent-bit --HEAD

In more detail about fluent-bit, please refer to the official fluent-bit document: http://fluentbit.io/documentation/

Happy logging!

GroongaのRustバインディングを書いた

Rustがそろそろ1.0.0ということで最初のRustのリリースの時とだいぶ異なった言語になったらしい、
とのことで再度触れてみました。

触れる題材としてGroongaのバインディングを書いてみることに。

そうして出来上がったのが、Rust + GroongaでRuroonga(るーるんが)です。

(○[○]roongaの名前空間がそろそろ苦しい…。)

最近Rustにはcargoというパッケージマネージャが開発され、それが使われているとのことなのでCargoを使ったプロジェクトになっています。

バインディングを手で書いていたのですが、rust-bindgenがRustのHEAD(1.1.0-dev)で使えたのでRustをビルドしてrust-bindgenで作成しなおしました。

RuroongaはひとまずHaskellでのバインディングと同じように、
GroongaコマンドがRustから発行できること、までを目指して開発しました。

Ruroongaをつい先程Cargoのレジストリに登録したのでCargo.tomlに

ruroonga = "0.1.0"

と指定して使いはじめることができます。

haroonga-httpdを書いた話

前にGroongaのHaskellバインディングのHaroongaを書いたので、どうせならHTTP越しにGroongaを使ってみたいと思っていたらつい書いてしまったというお話。

Github – haroonga-httpd

内部でHaroongaに依存しており、Groongaをライブラリとして呼んで使っています。

WebアプリケーションのフレームワークにはScotty(HaskellのSinatraクローン)を使っています。ScottyはSinatraのAPIに似せて作られていますが、内部で使っているWAIがConcurrentなため、ScottyもちゃっかりConcurrentになっています。

GroongaのHTTPのインターフェースほどしっかりパラメータをパースすると言うことはしていないです。。。

http://localhost:3000/d/<Groonga command>

のようなURLでアクセスするとGroongaのcommandがharoonga-httpdの動いているマシンで実行され、結果がGroonga互換のjsonで返ってくるようになっています。

起動のさせ方はGithubのREADMEなどを見ていただけると。

HaskellでもちゃんとGroongaがライブラリとして使えていますね!!

MikutterInstallBattle with nokogiri 1.6.5 at develop branch

#mikutterinstallbattle with nokogiri 1.6.5

Homebrewでlibxml2を入れている場合は、OS Xのライブラリと競合しないようにkeg-onlyフラグが付けられている。

これは、Cellarには入れるが、system wideに参照する事ができない状態にしてインストールするという意味。

それを参照するには以下の記述をbashrcなどに加えれば良い。

export PKG_CONFIG_PATH=/usr/local/opt/libffi/lib/pkgconfig:/usr/local/opt/libxml2/lib/pkgconfig:$PKG_CONFIG_PATH

libffiは要らないかも知れない。

おしまい。