気の向くままに辿るIT/ICT/IoT
インターネット

AsteriskでCDR/通話明細記録 by PostgreSQL

ホーム前へ次へ
Asteriskとは?

AsteriskでCDR/通話明細記録 by PostgreSQL

AsteriskでCDR/通話明細記録 by PostgreSQL

2026/02/21

 運用中のpjsipなAsteriskに050 plus収容スマホ/パソコン/HT-813アナログ電話においてCDR/Call Detail Records/通話明細記録をPostgreSQLのテーブルに保存してみることにした話。

動機

 当初から必要になるだろうとは思っていた通話明細記録。

 動機は、故障によるテレビ買い替えに伴い、一昨日、通販で発注、設置依頼はしなかったものの、他所では、そうしたこともあるのでしょう、繁忙及びリサイクル回収もあり、注文時、電話確認とそのための時間帯選択、登録電話番号と違う番号がある場合の指定箇所があり、昨日と今朝、電話があって、昨日は電話を受けることができたものの、今朝は受けることができず、留守電に入っていたこと(残るは配達直前)。

 この時、連絡先を通話専用にすべく数年前に導入したATA+アナログ電話機+050 plusの固定電話機から今回、Asteriskに050 plusを収容、内線端末の1つとしたATA+アナログ電話機とスマホやパソコンという構成下で初めて050 plusの番号を着信に使うべく、今回の連絡先として指定、昨日は、予定通り、その番号にかかってきた為、アナログ電話機でもスマホでもPCでも電話をとることができる状態で留守電になることなく、着信を受けることができました。

 尚、アナログ電話ではATAの機能でもAsteriskの機能でも、スマホやPCもAsteriskの機能でナンバーディスプレイ契約がなくとも通知拒否していなければ、登録済みなら発信者の名前(そうでなければAGIで振り分けた非通知、公衆電話等の旨)と番号、少なくとも発信元の電話番号が表示されるようにしていますし、着信履歴も各内線端末に残る状況でした。

 一方、昨日連絡をくれた方は、念押しで、明日もこの電話番号で良いですよね?と確認してくれたものの、何らかの事情で配送員には伝わっていなかったのか、デフォルト登録してあってAsteriskに収容しておらず、その付近にいないと着信音が聴こえない可能性もあり、ナンバーディスプレイ契約もない、ひかり電話の番号の方にかかってきたことで案の定、気づかずに留守電になってしまった次第。

 配送員の方は、お忙しいので折り返し電話というのも気がひけるため、留守電にはしたくなかったからこその番号指定だったので、この場合、着信記録が残っていたとしても微妙だったわけですが。

 他方、長年各所へ連絡先として登録済み、まだ変更していないながらも、ひかり電話は、解約予定なのでどうしたものか迷っていたものの、数日前Asteriskに収容すべく、サラッと試してみるとできなかったので先延ばしに、こんなことなら、突き詰めて、やっておくんだったなと思いました。

 が、それとは別にAsteriskに収容済みな050 plusについては外線着信時に指定の各内線端末に履歴が残るのでまだ良いものの、ひかり電話を単独でそのままにしておくと、着信記録が残らないため、相手が番号通知してくれていたところで、どこにも残っておらず、折返しができない、今回は留守電に入れてくれましたし、今朝時点の電話は、予定通りの時間帯に伺うので...という連絡だったので事なきを得ましたが、そうでなかったら、また、今後もこういうことが起きたら...。

 050 plusでの着信についても、それぞれ登録済みであれば、発信元名と発信元番号が合わせて履歴として残るPCやスマホがシャットダウンしていた場合などはアナログ電話頼みも電話機の仕様上、番号というか数字しか表示、記録できず、名前が残らないため、既知の番号だったとしても、にわかに思いつかないこともある...などと思い、出られなかった場合も通話というか着信履歴は残しておいた方がよいなと、早急にやってみることに。

 もちろん、それでもサーバが落ちたら、結局残らないわけですが、それは、あってもレアなので。

 残る配達直前の電話ですが、配送員が気づいたのか、指定の050番号にかけてきてくれたので留守電になることなく、無事、着信を受けることができました(ちなみに予定より最小3時間、最大6時間も早く届けてくださるというラッキーな連絡)。

 ちなみに、外線着信時には、3台内線端末を指定してあり、この時、スマホで取って、あろうことか、うっかり、受話ボタンではなく、切断ボタンをタップしてしまい、あ!と思ったものの、アナログ電話やパソコンでは、まだ着信音が鳴っており、もしかしてと思った通り、外線がまだ生きていて受けることができたという、確かにダイヤルプラン上は、そうなるんでしょうが、複数指定した内線端末の1つで切断したとしても外線が切れることもなく、残る端末で受ければよく、影響ないという想定していなかった興味深い発見をするに至りました。

PostgreSQLでTable作成

 というわけで、ここからは、Asterisk+PostgreSQLに倣いつつ、少しアレンジを加えることに。

 CDRをPostgreSQLで扱う場合、Asteriskをソースからconfigureした後、make menuselectでcdr_pgsqlを有効にしておく必要があるということで、その後、make、make installしておきます。

raspberry_pi_os $ grep asterisk /etc/passwd
asterisk:x:1001:1001::/home/asterisk:/bin/bash
raspberry_pi_os $ grep asterisk /etc/group
asterisk:x:1001:
raspberry_pi_os $

 その際、作っているはずではありますが、Linux上にasteriskユーザーが存在するか確認、存在しなければ作成します。

raspberry_pi_os $ sudo su asterisk
raspberry_pi_os $ psql myastdb
ユーザー asterisk のパスワード:
psql (15.15 (Raspbian 15.15-0+deb12u1))
"help"でヘルプを表示します。
 
myastdb=# CREATE TABLE cdr (
  date     date         NOT NULL DEFAULT CURRENT_DATE,
  calldate   time         NOT NULL ,
  clid     varchar (80)     NOT NULL ,
  src     varchar (80)     NOT NULL ,
  dst     varchar (80)     NOT NULL ,
  dcontext   varchar (80)     NOT NULL ,
  channel   varchar (80)     NOT NULL ,
  dstchannel  varchar (80)     NOT NULL ,
  lastapp   varchar (80)     NOT NULL ,
  lastdata   varchar (80)     NOT NULL ,
  duration   int         NOT NULL ,
  billsec   int         NOT NULL ,
  disposition varchar (45)     NOT NULL ,
  amaflags   int         NOT NULL ,
  accountcode varchar (20)     NOT NULL ,
  uniqueid   varchar (32)     NOT NULL ,
  timestamp   timestamp       NOT NULL DEFAULT CURRENT_TIMESTAMP,
  userfield   varchar (255)     NOT NULL
);
CREATE TABLE
myastdb=# \d
リレーション一覧
スキーマ | 名前 | タイプ | 所有者
----------+-----------+----------+----------
public | cdr | テーブル | asterisk
(1 行)
 
myastdb=# \d cdr
テーブル"public.cdr"
列 | タイプ | 照合順序 | Null 値を許容 | デフォルト
------+-----------------------+----------+---------------+------------
... | ... | ... | ... |
 
myastdb=# exit
raspberry_pi_os $ exit
raspberry_pi_os $

 今度は、asteriskユーザーに切り替えて既にcreatedbコマンドで作成したデータベースに[psql データベース名]として接続。

 リンク先では、別途ユーザーを作成していますが、ここでは、asteriskユーザーでテーブルを作成しました。

 CREATE TABLE文でテーブルを作成、[\d]でテーブルを、[\d テーブル名]でテーブル定義を正しく作成出来たことを確認しておきます。

 リンク先では、最初のカラム名がcalldateでtime型ですが、これは、取得できる入力データがそのカラム名でtime型を求めているからということのようです。

 自身は、日をまたいで保存した場合に確認時用にdate型が欲しかったのでDEFAULT CURRENT_DATEとして、日付時刻を使った何らかのソートをしたくなった時、timestamp型が欲しかったのでDEFAULT CURRENT_TIMESTAMP(now()でも可)としてカラムを2つ追加してみました。

 最初、calldate date型、calltime time型としてみたところ、日付は正しく取れた一方で時間はとれず、NOT NULL制約エラーとなったので、こうしました。

raspberry_pi_os $ cat /etc/asterisk/cdr_pgsql.conf
[global]
hostname=localhost
port=5432 ; ポート
dbname=DBNAME ; DB名
user=USERNAME ; ユーザ名
password=PASSWORD ; パスワード
table=cdr ; テーブル名
raspberry_pi_os $

 リンク先の通り、cdr_pgsql.confを他をデフォルトとするなら、データベース名、ユーザー名、パスワードを適宜編集の上、このようにします。

raspberry_pi_os $ sudo su asterisk
raspberry_pi_os $ asterisk -vvvvvr
CLI > module load cdr_pgsql
CLI >
...

 Asterisk CLIで[module load crd_pgsql](もしくは、OS CLIでasterisk -rx "module load cdr_pgsql")しておきます。

 外線なら、050番号やひかり番号へ、もしくは、内線で電話をかけます(着信を受ける必要なく、ログが出るか、呼び出し音が鳴った時点で切ってOK)。

raspberry_pi_os $ psql myastdb
ユーザー asterisk のパスワード:
psql (15.15 (Raspbian 15.15-0+deb12u1))
"help"でヘルプを表示します。
 
myastdb=# select * from cdr;
...
myastdb=# exit
raspberry_pi_os $ exit
raspberry_pi_os $

 そしてテーブルを確認するとレコードが追加されているはずです。

 Raspberry Pi/ESP32/MQTT/Node.js/PostgreSQLで温湿度環境モニタを自作のようにすれば、PostgreSQLのDB・テーブルにアクセスしてブラウザ上で結果表示できるので端末のみならず、スマホ・タブレットやパソコンで確認することもできますね。

ホーム前へ次へ