IIJmioクーポンスイッチAPIで得たデータをZabbixに投げる

# これはなに？
SIMフリー版iPhoneを買ったので、SoftBankからIIJmioにMNPした筆者が、残りクーポン量を知るべく、Perlを使って作ったいろいろの話。をする予定で、書き始めたけれど、とりあえず、ZabbixテンプレートとPerlスクリプトだけ張った状況のヒドい文書。

# 前提
- Zabbix {Server, Sender}のインストールが完了している
- Perlのモジュールが足りなければ自分で追加する根性
- 筆者は、動けばいいと思って書いたので、コードの汚さは気にしない

# そもそもIIJmioのAPIって？
[IIJmioクーポンスイッチAPI](https://www.iijmio.jp/hdd/coupon/mioponapi.jsp)
に書かれている仕様を読むと、残りクーポン量は、有効期限(expire)やクーポン種別(bundle, topup)別に取得出来る。

# データ設計
クーポン種別毎有効期限毎にデータが取得出来るが、そもそも有効期限は毎月変わっていくので、キーとして最初から登録するのには向かない。でも、得られる値をそのまま格納しておいた方が、あとから分析したくなったときに、なにかとうれしいよね。

つまり、AutoDiscoveryでキーを作成して、そのキーに対してデータを登録していく必要がある。

そこで、参考にしたページ

- [ZABBIX SENDER を利用したAutoDiscoveryの方法](http://www.zabbix.jp/node/3560)
- [LLD\(ローレベルディスカバリ\)を弄り倒せ、zabbix\_senderを併用してらくらく可視化](http://www.slideshare.net/takeshiyamane9/lld-zabbix)
- [IIJmioクーポンスイッチAPIを使って使用量グラフ作成](http://blog.osakana.net/archives/4921)

# こんなグラフが出来ます

30分おきにcronから起動するように設定しておくと、以下のようなグラフを得ることが出来ます

![chart2.png](https://qiita-image-store.s3.amazonaws.com/0/33756/cd89ddc5-7df2-a03f-40c0-33e95308134c.png)

クーポン残量の話のはずだったのに、パケット利用量のグラフですが、まぁ、似たようなもんです。

# あとは、若い者同士で……

Perlスクリプトは前半でクーポン残量を、後半で利用パケット料を利用している電話番号別に取得しています
Zabbixテンプレートも、ミニマムスタートプランを複数契約している人などは、契約毎にhost discoveryでhostを作っていくと、キレイにまとまるんじゃ無いかと思いますが、わたし自身がファミリーシェアプランを1契約しか持っていないので、そこまで汎用的に作る気力がありませんでした。

## Perl スクリプト


```Perl:iijmio.pl
#!/usr/bin/env perl

use strict;
use utf8;
use v5.10;

use Data::Dumper;
use JSON -support_by_pp;
use LWP;
use Time::Local 'timelocal';

my $ZABBIX_SENDER = "/usr/bin/zabbix_sender";
my $ZABBIX_HOST   = "iijmio";
my $ZABBIX_SERVER = "localhost";

my $developerid   = "<取得してね>";
my $usertoken     = "<取得してね>";

my @coupon_discovery_data;
my @packet_discovery_data;
my %hdoServiceCode2num;



my $now =timelocal(localtime());

my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst)
    = localtime(time);
$year += 1900;
$mon += 1;
my $today = sprintf("%04d%02d%02d", $year, $mon , $mday);


my $ua = LWP::UserAgent->new;
my $url="https://api.iijmio.jp/mobile/d/v1/coupon/";


my $req = HTTP::Request->new(GET => "$url");
$req->header("X-IIJmio-Developer" => "$developerid");
$req->header("X-IIJmio-Authorization" => "$usertoken");

my $res= $ua->request($req);


my $coupon = decode_json( $res->content );





unless ($coupon->{"returnCode"} = "OK"){
    print "Not OK";
    exit;
}
my $total ;
foreach my $item (@{$coupon->{"couponInfo"}->[0]->{"coupon"}}){
    $total += $item->{"volume"};
    push @coupon_discovery_data, {
        "{#CPNTYPE}"   => $item->{"type"} ,
        "{#CPNEXPIRE}" => $item->{"expire"}
    };

}
push @coupon_discovery_data, {
    "{#CPNTYPE}"   => 'TOTAL',
    "{#CPNEXPIRE}" => 'TOTAL',
};
push @{$coupon->{"couponInfo"}->[0]->{"coupon"}},{
    'type'   => 'TOTAL',
    'expire' => 'TOTAL',
    'volume' => $total
};
my $coupon_discovery = encode_json( {"data" => \@coupon_discovery_data});

my @cmd;

@cmd = (
    $ZABBIX_SENDER,
    "-z",
    $ZABBIX_SERVER,
    "-s",
    $ZABBIX_HOST,
    "-k iijmio.coupon.discovery",
    "-o",
    "'".$coupon_discovery."'"

);

system(join(" ",@cmd));


foreach my $item (@{$coupon->{"couponInfo"}->[0]->{"hdoInfo"}}){
    $hdoServiceCode2num{$item->{"hdoServiceCode"}} = $item->{"number"};
    push @packet_discovery_data, {
        "{#NUMBER}"   => $item->{"number"} ,
    };

}
my $packet_discovery = encode_json( {"data" => \@packet_discovery_data});

@cmd = (
    $ZABBIX_SENDER,
    "-z",
    $ZABBIX_SERVER,
    "-s",
    $ZABBIX_HOST,
    "-k iijmio.packet.discovery",
    "-o",
    "'".$packet_discovery."'"
);

#say join(" ",@cmd);
system(join(" ",@cmd));

sleep 30;


open( SENDER ,"| $ZABBIX_SENDER -z $ZABBIX_SERVER -T -i -")
    || die "can't fork: $!";


foreach my $item (@{$coupon->{"couponInfo"}->[0]->{"coupon"}}){

    local $SIG{PIPE} = sub { die "$ZABBIX_SENDER pipe broke" };
    my $key =
        "\"iijmio.coupon.rest[".
        $item->{"type"} .
        ",".
        $item->{"expire"}.
        "]\"";

    #  Each line of the input file must contain 4 whitespace delimited entries:
    #  <hostname> <key> <timestamp> <value>.

    print SENDER join(" ",( $ZABBIX_HOST,$key,$now,$item->{"volume"},)),"\n";


}


$url="https://api.iijmio.jp/mobile/d/v1/log/packet/";


$req = HTTP::Request->new(GET => "$url");
$req->header("X-IIJmio-Developer" => "$developerid");
$req->header("X-IIJmio-Authorization" => "$usertoken");

$res= $ua->request($req);


my $packet = decode_json( $res->content );

foreach my $hdoinfo (@{$packet->{"packetLogInfo"}->[0]->{"hdoInfo"}}){

    my $telnum = $hdoServiceCode2num{$hdoinfo->{"hdoServiceCode"}};
    foreach my $packetlog ( @{$hdoinfo->{"packetLog"}} ){

        my $date = $packetlog->{"date"};
        my $y = substr($date,0,4);
        my $m = substr($date,4,2);
        my $d = substr($date,6,2);
        my $t = timelocal(59,59,23,$d,$m-1,$y-1900);


        next if ($now - $t > 4000);
        if ( $date eq $today ){ $t = $now};


        foreach my $w ("withCoupon","withoutCoupon"){
            local $SIG{PIPE} = sub { die "$ZABBIX_SENDER pipe broke" };
            my $key =
                "\"iijmio.packets.used[".
                $telnum .
                ",".
                $w.
                "]\"";

            #  Each line of the input file must contain
            # 4 whitespace delimited entries:
            #  <hostname> <key> <timestamp> <value>.

            print SENDER join(" ",
                              ( $ZABBIX_HOST,$key,$t,$packetlog->{$w},)
                          ),
                          "\n";
        }
    }
}

close SENDER || die "bad $ZABBIX_SENDER: $! $?";

exit;


```
## Zabbix側テンプレート

```XML:IIJmio_template.xml
<?xml version="1.0" encoding="UTF-8"?>
<zabbix_export>
    <version>3.2</version>
    <date>2017-01-31T15:55:24Z</date>
    <groups>
        <group>
            <name>iijmio</name>
        </group>
        <group>
            <name>Templates</name>
        </group>
    </groups>
    <templates>
        <template>
            <template>Template IIJmio mobile</template>
            <name>Template IIJmio mobile</name>
            <description/>
            <groups>
                <group>
                    <name>iijmio</name>
                </group>
                <group>
                    <name>Templates</name>
                </group>
            </groups>
            <applications>
                <application>
                    <name>Coupon</name>
                </application>
                <application>
                    <name>Packets</name>
                </application>
            </applications>
            <items/>
            <discovery_rules>
                <discovery_rule>
                    <name>coupon discovery rule</name>
                    <type>2</type>
                    <snmp_community/>
                    <snmp_oid/>
                    <key>iijmio.coupon.discovery</key>
                    <delay>0</delay>
                    <status>0</status>
                    <allowed_hosts/>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <filter>
                        <evaltype>0</evaltype>
                        <formula/>
                        <conditions/>
                    </filter>
                    <lifetime>30</lifetime>
                    <description/>
                    <item_prototypes>
                        <item_prototype>
                            <name>Rest of Coupon {#CPNTYPE} / {#CPNEXPIRE}</name>
                            <type>2</type>
                            <snmp_community/>
                            <multiplier>1</multiplier>
                            <snmp_oid/>
                            <key>iijmio.coupon.rest[{#CPNTYPE},{#CPNEXPIRE}]</key>
                            <delay>0</delay>
                            <history>190</history>
                            <trends>365</trends>
                            <status>0</status>
                            <value_type>3</value_type>
                            <allowed_hosts/>
                            <units>B</units>
                            <delta>0</delta>
                            <snmpv3_contextname/>
                            <snmpv3_securityname/>
                            <snmpv3_securitylevel>0</snmpv3_securitylevel>
                            <snmpv3_authprotocol>0</snmpv3_authprotocol>
                            <snmpv3_authpassphrase/>
                            <snmpv3_privprotocol>0</snmpv3_privprotocol>
                            <snmpv3_privpassphrase/>
                            <formula>1048576</formula>
                            <delay_flex/>
                            <params/>
                            <ipmi_sensor/>
                            <data_type>0</data_type>
                            <authtype>0</authtype>
                            <username/>
                            <password/>
                            <publickey/>
                            <privatekey/>
                            <port/>
                            <description/>
                            <inventory_link>0</inventory_link>
                            <applications>
                                <application>
                                    <name>Coupon</name>
                                </application>
                            </applications>
                            <valuemap/>
                            <logtimefmt/>
                            <application_prototypes/>
                        </item_prototype>
                    </item_prototypes>
                    <trigger_prototypes/>
                    <graph_prototypes/>
                    <host_prototypes/>
                </discovery_rule>
                <discovery_rule>
                    <name>iijmio Packet discovery</name>
                    <type>2</type>
                    <snmp_community/>
                    <snmp_oid/>
                    <key>iijmio.packet.discovery</key>
                    <delay>0</delay>
                    <status>0</status>
                    <allowed_hosts/>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <filter>
                        <evaltype>0</evaltype>
                        <formula/>
                        <conditions/>
                    </filter>
                    <lifetime>30</lifetime>
                    <description/>
                    <item_prototypes>
                        <item_prototype>
                            <name>packet used {#NUMBER} with Coupon</name>
                            <type>2</type>
                            <snmp_community/>
                            <multiplier>1</multiplier>
                            <snmp_oid/>
                            <key>iijmio.packets.used[{#NUMBER},withCoupon]</key>
                            <delay>0</delay>
                            <history>190</history>
                            <trends>365</trends>
                            <status>0</status>
                            <value_type>3</value_type>
                            <allowed_hosts/>
                            <units>B</units>
                            <delta>0</delta>
                            <snmpv3_contextname/>
                            <snmpv3_securityname/>
                            <snmpv3_securitylevel>0</snmpv3_securitylevel>
                            <snmpv3_authprotocol>0</snmpv3_authprotocol>
                            <snmpv3_authpassphrase/>
                            <snmpv3_privprotocol>0</snmpv3_privprotocol>
                            <snmpv3_privpassphrase/>
                            <formula>1048576</formula>
                            <delay_flex/>
                            <params/>
                            <ipmi_sensor/>
                            <data_type>0</data_type>
                            <authtype>0</authtype>
                            <username/>
                            <password/>
                            <publickey/>
                            <privatekey/>
                            <port/>
                            <description/>
                            <inventory_link>0</inventory_link>
                            <applications>
                                <application>
                                    <name>Packets</name>
                                </application>
                            </applications>
                            <valuemap/>
                            <logtimefmt/>
                            <application_prototypes/>
                        </item_prototype>
                        <item_prototype>
                            <name>packet used {#NUMBER} without Coupon</name>
                            <type>2</type>
                            <snmp_community/>
                            <multiplier>1</multiplier>
                            <snmp_oid/>
                            <key>iijmio.packets.used[{#NUMBER},withoutCoupon]</key>
                            <delay>0</delay>
                            <history>190</history>
                            <trends>365</trends>
                            <status>0</status>
                            <value_type>3</value_type>
                            <allowed_hosts/>
                            <units>B</units>
                            <delta>0</delta>
                            <snmpv3_contextname/>
                            <snmpv3_securityname/>
                            <snmpv3_securitylevel>0</snmpv3_securitylevel>
                            <snmpv3_authprotocol>0</snmpv3_authprotocol>
                            <snmpv3_authpassphrase/>
                            <snmpv3_privprotocol>0</snmpv3_privprotocol>
                            <snmpv3_privpassphrase/>
                            <formula>1048576</formula>
                            <delay_flex/>
                            <params/>
                            <ipmi_sensor/>
                            <data_type>0</data_type>
                            <authtype>0</authtype>
                            <username/>
                            <password/>
                            <publickey/>
                            <privatekey/>
                            <port/>
                            <description/>
                            <inventory_link>0</inventory_link>
                            <applications>
                                <application>
                                    <name>Packets</name>
                                </application>
                            </applications>
                            <valuemap/>
                            <logtimefmt/>
                            <application_prototypes/>
                        </item_prototype>
                    </item_prototypes>
                    <trigger_prototypes/>
                    <graph_prototypes/>
                    <host_prototypes/>
                </discovery_rule>
            </discovery_rules>
            <httptests/>
            <macros/>
            <templates/>
            <screens/>
        </template>
    </templates>
</zabbix_export>

```