Metabaseでlog4jを使ってログを出力する

pkgsrc/www/metabaseを最新にアップデートするのは怠けているのだが、手元ではほぼ常に最新版を使っている。 pkgsrc/www/metabaseのインストールするrcスクリプトには、log4jによりログを出力する設定が含まれている。 また、そのrcスクリプトが利用するlog4j2.xmlという設定ファイルの雛形も含まれている。 なので、pkgsrcからMetabaseをインストールすれば、/var/log/metabase/metabase.logに、設定されたようにログが出力される。

log4jによりログを出力するのは、私の用途では重要なのだが、少なくとも私がMetabaseを使い始めた時にはあまり情報がなかったように思う。 もうずいぶんと前の話なので、今は十分に説明するウェブページが世間にはあるようだ。

Grafanaには、BASIC認証を設定できない

Grafanaを簡単にどういうものか説明できるほど良く理解していないが、私の使い方で言えば、時系列データを保存しているデータベースがあって、その内容を折れ線グラフでプロットして、その値によってアラートを出すように設定できるダッシュボードのウェブページである。 ビジネス・インテリジェンス・システムのようなものであるような気もする。

私は、少し古いがpkgsrc/www/grafanaから11.0.0をインストールし、データベースは、pkgsrc/databases/influxdbを手元でアップデートしてInfluxDB 1.8.10をインストールして使っている。 ウェブサーバーがないと使えない訳ではないと思うが、Apache httpdをリバースプロキシーとして利用している。

Grafanaには、もちろんログイン機能があって、ログインしなければダッシュボードを見ることはできない。 そもそもやりたかったのは、そもそもGrafanaのログイン画面へ行くこともできないようにすることだった。 そうだとすると、一番簡単なのは、BASIC認証を設定することであるように思えた。

しかし、BASIC認証は使えない。 と言うのは、ユーザー追加をする際に、Grafana自体が自身のAPIを利用する場合にBASIC認証を利用しているからであるようである。 Apache httpdでBASIC認証した上で、ユーザー追加をすると、追加したユーザーでしかログインできなくなるばかりか、そのユーザーからログアウトすることもできなくなってしまう。

おとなしく、Grafana備え付けのログイン画面を使っておくのが一番良さそうである。

Windows 11でwgetを使ってhttpsなウェブサイトから情報を取得する

Windows 11でhttpsなウェブサイトから情報を取得したいのだが、ウェブ上にある多くの古いwgetのWindows用のバイナリーは、TLS 1.2以降に対応しておらず私の接続先には利用できなかった。 また、このwgetを動かす環境は、ユーザー認証付きのHTTPプロキシーサーバーを経由しないとイントラネット外のウェブサイトへ接続することはできない。 このような状況でWindows 11のマシンでwgetを利用する方法を書いておく。

wgetのバイナリーを入手する

Windows binaries of GNU Wgetで公開されているwgetバイナリーは、新しいTLSのバージョンにも対応していた。 他にもおそらく使えるバイナリーを配布している所はあるかもしれないが、具体的には確認していない。

具体的には、バージョン1.21.4のバイナリーをダウンロードして利用した。

設定値をファイルに格納する

ユーザー認証付きHTTPプロキシーサーバーを利用する必要があり、これらを毎回コマンドライン引数として入力するのは煩雑になる。 また、パスワードをコマンドライン引数として与えるのも、パスワードが画面上に表示されてしまい、うれしくない。

ということで、設定値はwgetrc.txtというテキストファイルに予め記入しておくことにした。 その内容は以下のようにした。

> type wgetrc.txt
use_proxy=on
http_proxy=http://10.1.1.1:8080/
https_proxy=http://10.1.1.1:8080/
proxy_user=(YOUR USERID)
proxy_password=(YOUR PASSWORD)
check_certificate=off

ここで、check_certificate=offはTLS証明書のチェックを省略している。 これは良い習慣ではない。

実行例

このwgetrc.txtファイルを使いつつ、ウェブサイトから情報を取得するには、以下のようにすれば良い。

> wget.exe --config=wgetrc.txt -nc -r https://www.ryoon.net/

MetabaseをOracle databaseへクエリーするAPIサーバーとして利用する

Oracle databaseに各クライアントPC上のMicrosoft Excel VBAからアクセスしようとすると、Oracle Instant Clientのインストールが必要になる。 ODBC経由だとデータソースの設定が必要になり、皿に初期設定は手間がかかるが、Excel VBAからアクセスする程度であれば、ADO DB経由でも問題ない。 この場合には、tnsnames.oraに接続先を設定する必要はなく、接続文字列に直接接続先を記載すれば良いので、とりあえずOracle Instant Clientをインストールさえして置けば良い。 ただ、Oracle社の用意しているOracle Instant Clientのインストーラーは冗長かつ何をしているか分かりにく、インストールに失敗するとインストーラーはまた別のディレクトリーにインストールしてしまうので、同じ緩急を作るのも面倒だ。 これについては、必要なファイルと処理のみを解析して抜き出したWindowsバッチファイルを用意しているので、個人的には解決はしているが…。

とは言っても、あくまでWindowsバッチファイルであり、環境変数の設定は手作業でするようになってもいるので、インストールには手間がかかる。 そもそもOracle Instant Clientをインストールしない方法を探していた。

過去にはJRubyからJDBCを使ってOracle databaseにアクセスし、結果を返すサーバーを書いてもいたのだが、利用者の認証や権限設定も欠けており、起動させておくのも面倒なので、実用できてはいなかった。

metabaseのドキュメントを読んでいたら、アクセストークンを発行して、それによりREST APIでMetabaseに登録されたデータベースにクエリーを投げて、その結果をJSONやCSV形式で返してくれる仕組みがあった。 今回は本来は使うべきであるセッションIDは使わないのだが、curlコマンドで試した内容を書いておく。

アクセスする例

最初に、前提となる情報を書いておく。

今回使うユーザーグループ権限のAPIキー
mb_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=
MetabaseサーバーのURI (都合上HTTPでしかアクセスできない)
http://mbserv.example.com/
アクセスするデータベースの番号 (JDBC経由で接続できるようにウェブUIで設定されている)
2

このMetabaseサーバーが設置され、クライアントのWindows PCが接続されているイントラネットは、イントラネット外の80版ポートに接続するにはHTTPプロキシサーバーを経由する必要がある。 だが、イントラネット内にあるMetabaseサーバーにはHTTPプロキシサーバー経由ではアクセスできないので、HTTPプロキシサーバーを掴ない設定も重要である。

グループの一覧を取得する。 これはOracle databaseには無関係なMetabaseの機能に対する問い合わせである。

$ curl --noproxy mbserv.example.com -H 'x-api-key: mb_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=' -X GET 'http://mbserv.example.com/api/permissions/group'

MBQL JSON形式でSQLのクエリーの結果を取得する。 結果はMBQLのJSON形式であり、前半にデータが、後半にコラム情報が収録されており、Excel VBAであればVBA-FastDictionaryVBA-FastJSONを使えば解析しデータを利用するのが幹太になる。

$ curl --noproxy mbserv.example.com -H 'x-api-key: mb_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=' -H 'Content-Type: application/json' -X POST 'http://mbserv.example.com/api/dataset' -d '{ "database": 2, "native": { "query": "select * from myschema.MYTABLE1" }, "type": "native"}'

CSV形式でSQLのクエリーの結果を取得する。

$ curl --noproxy mbserv.example.com -H 'x-api-key: mb_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=' -H 'Content-Type: application/x-www-form-urlencoded' -X POST 'http://mbserv.example.com/api/dataset/csv' -d 'query={ "database": 2, "native": { "query": "select * from myschema.MYTABLE1" }, "type": "native"}'

これで、Oracle Instant Clientをインストールせずに、クライアントWindows PCからOracle databseの内容を参照できるようになった。

MetabaseでActive Directory認証する際に、ユーザーIDでも電子メールアドレスでも、ログインユーザーIDとして使えるようにする

MetabaseでActive Directory認証するで書いておいたような設定でMetabaseを運用して来たのだが、Metabaseのログイン画面にはログインユーザーID欄に「ユーザーネームまたはメールアドレス」と書かれているためか、電子メールアドレスを入力してログインできないという苦情を言う人が多いという問題があった。 駄目だったらユーザーIDでログインできるか試せば良いと私などは思うが、そんな発想にならない人ばかりに囲まれている。 そもそもなぜそういう発想をすることができるかということも説明しても理解してもらえないので、ユーザーIDでも電子メールアドレスでもログインするしかないだろう。

と言うことで、Active Directoryの項目を調べてみると、以下のような項目が使えそうであった。

  • ユーザーIDはsAMAccountNameという項目であり、既に利用している。
  • ユーザー認証に利用できる電子メールアドレスは、userPrincipalNameという項目になっているらしい。
  • 電子メールアドレスはmailという項目にも格納されているらしい。

と言うことで、これら3つのいずれかをloginに使えば良さそうだ。

以下のように設定していたので、変更しよう。

(&(sAMAccountName={login}))

変更後は以下のようにした。

(&(|(sAMAccountName={login})(mail={login})(userPrincipalName={login}))(objectClass=user))

これで、電子メールアドレスでもユーザーIDでもいずれでもログインIDとして与えてもログインできるようになった。

NetBSDでFPAG開発を始めてみる(NVCとVHDL)

この記事は、NetBSD Advent Calendar 2025の25日目の記事です。

はじめに

本当は、PyRTLで書いたロジックをTnag Nano 9Kで動かしてみたいのですが、これから勉強しないといけないので、しばらく先に進めそうにありません。 と言うことで、22日目23日目でVHDLを使ってみていましたが、その際に試していたNVCというVHDLのシミュレーターについて、試したことを書いておきたいと思います。

NVCできること

NVCは、GHDLとは違い、合成をすることはできません。 あくまで、IEEE 1076-2008のほとんどをシミュレーションできるだけのようです。 VHDLについては、普通の利用者は、GOWIN FPGA Designerを使うでしょうから、良いシミュレーターであるだけでも大きな意味があるのだと思います。 NVCはJ-Core Open Processorでも使われているようです。

NVCをインストールする

pkgsrc/cad/nvcとして、nvc-1.18.2を用意しました。 この後にインポートしておきたいと思います。

と言うことで、以下のようにインストールすれば良いでしょう。

# cd /usr/pkgsrc/cad/nvc
# make install

これによって、/usr/pkg/bin/nvcがインストールされます。 これを使って、22日目のGHDLによるシミュレーション用のMakefileに、NVCを使ったパターンも追加してみます。 analysisをするにはanalysisnvcターゲット、elaborateにはelaboratenvcターゲット、シミュレーションを実行してvcdウェーブフォームファイルを得るにはrunnvcターゲットを用意しました。

$ cat Makefile
TARG=   counter

GHDL_FLAGS+=    -fsynopsys

.PHONY: analysis elaborate run clean analysisnvc elaboratenvc runnvc

analysis: ${TARG}.vhdl
        ghdl -a ${GHDL_FLAGS} ${TARG}.vhdl
        ghdl -a ${GHDL_FLAGS} ${TARG}_tb.vhdl

analysisnvc: ${TARG}.vhdl ${TARG}_tb.vhdl
        nvc -a ${TARG}.vhdl ${TARG}_tb.vhdl

elaborate: work-obj93.cf
        ghdl -e ${GHDL_FLAGS} ${TARG}
        ghdl -e ${GHDL_FLAGS} ${TARG}_tb

elaboratenvc: analysisnvc
        nvc -e counter_tb

run: elaborate
        ghdl -r ${GHDL_FLAGS} --time-resolution=ns ${TARG}_tb --vcd=counter.vcd --stop-time=1ms

runnvc: elaboratenvc
        nvc -r --format=vcd --wave=counter-nvc.vcd --stop-time=1ms counter_tb

clean:
        rm -f counter.vcd
        rm -f work-obj93.cf
        rm -f counter-nvc.vcd
        rm -fr work

ただし、nvcの生成したcounter-nvc.vcdファイルのタイムスケールはfs単位になっていて、変更ができないようです。

結果のvcdファイルをGtkWaveで表示してみる

Zoom-outしていくと、下図のように表示できました。 既定の表示は非常にZoom-inされた状態ですが…。

これで、GHDLだけでなくシミュレーションを実行できるようになりました。 検証も確実さを上げることができそうです。

NetBSDでFPAG開発を始めてみる(PyRTL) 準備編

この記事は、NetBSD Advent Calendar 2025の24日目の記事です。

はじめに

21日目から23日目にかけて、安価に購入したFPGA基板であるTang Nano 9Kのための開発環境をNetBSD上に整え、基本的にはNetBSDだけで開発できることを確認しました。 でも、合成や配置配線にもベンダー特有の最適化が必要であるかもしれません。 また、GOWIN FPGA Designerでは、A/Dコンバーターなどの各種ロジックやArm Cortex-M0やRISC-Vなどのアーキテクチャーのマイクロコントローラーを選択するメニューがありました。 どこまで無料で使えるのか分かっていませんが、そういうものはNetBSD上では使いようがなさそうです。

とは言え、私がVerilogを学んだり、Tang Nano 9Kを購入したのは、PyRTLという教育用のHDLを使ってみたかったためでした。 なので、そういう便利なものは使えなくても困りません。 PyRTLはVerilogのソースコードを出力してくれるので、21日目のように作業できれば、最適化は別として、それで良いとも言えます。

ですが、マイナーなものを使うと、世界で最初に困る人になってしまいがちです。 PyRTLにはJupyer Notebook/JupyeterLabで学べるような教材が用意されているのですが、少なくとも2025年12月28日現在lpkgsrc経由で利用できるJupyter Notebook/JupyterLabではエラーになりウェーブフォームをウェブブラウザー上では見ることができません。 せっかくPyRTLにはシミュレーション機能が内蔵されているのに、それを活用することができません。

おそらくNetBSDで作業しているから発生する問題ではないと思われるものの、pkgsrc/cad/py-PyRTL-0.12が壊れているのは困りますので、直すことにしました。

エラーの内容

まず、私は以下のようなJupyter NotebookとJupyterLabのパッケージをインストールしています。 これ以外にも関連するものはありますが、そこまで厳密である必要はないでしょう。

py314-jupyter-lsp-2.3.0
py314-jupyter_server_terminals-0.5.3
py314-jupyter_client-8.7.0
py314-jupyterlab-4.4.10
py314-jupyter_core-5.9.1
py314-jupyterlab-pygments-0.3.0
py314-jupyter_events-0.12.0
py314-jupyterlab-server-2.28.0
py314-jupyter_server-2.17.0

エラーの内容は非常に簡単です。ipynb-examples/example1-combologic.ipynbと言う教材のStep 2の3個目のセルのsim.tracer.render_trace(symbol_len=2)が失敗します。 エラーメッセージはJavascript Error: $ is not definedです。 FirefoxのDevelopert toolのconsoleには何も出ていませんが、Jupyter Notebook/JupyterLabの画面上に表示されるエラーです。

実を言うと、ipynb-examples/example1-combologic.ipynbは、examples/example1-combologic.pyから自動生成されています。 と言うことで、examples/example1-combologic.pyの内容をそのままJupyter Notebook/JupyterLabの1つのセルで実行して、どこがいけないのか調査することにしました。

エラーを調査する

ipynbファイルを保存すると、以下のような内容が含まれています。 この内容は元々のipynbにはありません。 どこかで自動的に挿入されているはずです。

(snip)
$.getScript("https://cdnjs.cloudflare.com/ajax/libs/wavedrom/1.6.2/skins/default.js"),
$.getScript("https://cdnjs.cloudflare.com/ajax/libs/wavedrom/1.6.2/wavedrom.min.js"),
(snip)

ここまで特徴的であれば、/usr/pkg/lib以下を探しても迷うことはありません。 pyrtl/simulation.pyというファイルに含まれていることが分かりました。 そして、この$は、jQueryが提供されることが期待されているようです。 ですが、私のインストールしているJupyter NotebookもJupyterLabも、ウェブブラウザー上でjQueryの$は提供していないようです。 少なくとも$.getScript関数は使えません。

どこかでjQueryのgetScript関数は使うなと言われたような記憶もありますが、最新版では使えるのかもしれません。 いずれにしても、PyRTLの教材を動かすのには十分なはずです。 と言うことで、jQueryを読み込んだ後に、問題の箇所を実行するようにすれば良さそうです。

エラーを修正する

オリジナルのPyRTL-0.12のソースコードで関連する箇所を以下に示します。 この中の1775行目からのjs_code変数の中身を書き換えれば良さそうです。 改めて見ると、問題の箇所は、当然ですがJupyter Notebook/JupyterLabで実行した場合のみ呼び出されるようになっています。

  1760          if _currently_in_jupyter_notebook():
  1761              from IPython.display import (
  1762                  HTML,
  1763                  Javascript,
  1764                  display,
  1765              )
  1766
  1767              from pyrtl.visualization import trace_to_html
  1768
  1769              htmlstring = trace_to_html(
  1770                  self, trace_list=trace_list, sortkey=_trace_sort_key
  1771              )
  1772              html_elem = HTML(htmlstring)
  1773              display(html_elem)
  1774              # print(htmlstring)
  1775              js_stuff = """
  1776              $.when(
  1777              $.getScript("https://cdnjs.cloudflare.com/ajax/libs/wavedrom/1.6.2/skins/default.js"),
  1778              $.getScript("https://cdnjs.cloudflare.com/ajax/libs/wavedrom/1.6.2/wavedrom.min.js"),
  1779              $.Deferred(function( deferred ){
  1780                  $( deferred.resolve );
  1781              })).done(function(){
  1782                  WaveDrom.ProcessAll();
  1783              });"""
  1784              display(Javascript(js_stuff))

Jupyter NotebookやJupyterLabを実行できるウェブブラウザーであれば、fetch関数やpromiseのサポートは持っているはずな気がします。 と言うことで、安直ですがfetchして実行する関数を用意し、jQueryを読み込んだ後に、promiseを使って、既存のロジックを実行させることにしました。

以下のようなパッチを作成して適用しました。

@@ -1773,6 +1773,16 @@ class SimulationTrace:
             display(html_elem)
             # print(htmlstring)
             js_stuff = """
+            function fetchAndRunScript(uri) {
+              return fetch(uri)
+                .then(resp => resp.text())
+                .then(scrtext => {
+                  const scrfunc = new Function(scrtext);
+                  scrfunc();
+                })
+                .catch(err => console.error('Cannot load script:', err));
+            }
+            fetchAndRunScript("https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js").then(() => {
             $.when(
             $.getScript("https://cdnjs.cloudflare.com/ajax/libs/wavedrom/1.6.2/skins/default.js"),
             $.getScript("https://cdnjs.cloudflare.com/ajax/libs/wavedrom/1.6.2/wavedrom.min.js"),
@@ -1780,7 +1790,7 @@ class SimulationTrace:
                 $( deferred.resolve );
             })).done(function(){
                 WaveDrom.ProcessAll();
-            });"""
+            });});"""
             display(Javascript(js_stuff))
         else:
             self.render_trace_to_text(

こうすることで、ウェブブラウザー上でウェーブフォームを表示させることができるようになりました。 これで、FPGAに実装する前のチェックが簡単になります。

pkgsrc/cad/py-PyRTL-0.12nb1としてcommitしておこうと思います。

Metabaseでlog4jを使ってログを出力する

pkgsrc/www/metabaseを最新にアップデートするのは怠けているのだが、手元ではほぼ常に最新版を使っている。 pkgsrc/www/metabaseのインストールするrcスクリプト には、log4jによりログを出力する設定が含まれている。 また、そのrc...