【初心者向け】Zaif API×Pythonでプチフィンテック15 ログ出力処理の実装2

今回は、前回紹介したログ出力処理の流れを踏まえ、実際にログ出力をおこなうプログラムを作成していきます。

<スポンサーリンク>

ログ出力処理の流れ(再掲)

まず、前回紹介した、ログ出力処理の流れを再掲しておきます。後の実装段階では、こちらも併せてご覧いただくと、理解が深まると思います。

①Loggerインスタンスの生成

②デフォルトログレベルの設定

③ログフォーマットの定義

④ログ用ハンドラーの生成とフォーマットの適用

⑤Loggerインスタンスへハンドラーを紐付け

⑥ログの出力

実装

それでは実装に移りたいと思います。

まずはPyCharmで新規にPythonファイルを作成し、第13回目に作成したプログラムをコピーします。プログラム名は、ここでは「tradetest4」としておきます。

今回は、現物取引API特有の異常が発生した際に、適切に対処する方法を解説していきます。 現物取引API特有の異常 異常への対応については...

まず初めに記述すべきコードですが、loggingモジュールを使えるようにするため、このモジュールをインポートしておきます。

import requests
from urllib.parse import urlencode
import hashlib
import hmac
from time import time
import json
import logging #この行を追加

この後は、前掲の流れに従って、コードを追記していきます。

①Loggerインスタンスの生成

Loggerインスタンスの生成には、loggingモジュールの「getLogger」というメソッドを使います。記載する場所ですが、各処理が始まる前にログ出力設定を行う必要があるため、パラメータを羅列している箇所の直後ぐらいに記述します。

~省略~
AMOUNT = 1000
LIMIT = 200000

logger = logging.getLogger(__name__) #追加

~省略~

getLoggerには引数として、生成するLoggerインスタンスに付けたい名前を指定しまが、通常は「__name__」という、変数を指定します

「__name__」変数については多少説明が複雑になりますので、本記事では解説を割愛しますが、ここではLoggerを生成する時に指定する「おまじない」程度に捉えておいて頂ければと思います。

そして、上記コードでは、生成したLoggerインスタンスを「logger」という変数に格納しています。

②デフォルトログレベルの設定

続いて、生成したLoggerインスタンスにログレベルを設定します。

~省略~
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO) #追加
~省略

ログレベルは、Loggerインスタンスの「setLevel」というメソッドを用いて設定します。

設定するログレベルは、loggingモジュールに含まれる「INFO」や「ERROR」などの値を設定します

上記コードではINFOを指定することにより、INFO以上の全てのログを表示するように設定を行っています。

③ログフォーマットの定義

次に、生成するログのフォーマットを定義します。

~省略~
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
formatter = logging.Formatter('[%(levelname)s] %(asctime)s %(message)s') #追加
~省略

フォーマットは、loggingモジュールの「Formatter」というメソッドを用いて定義し、それを変数(ここでは「formatter」変数)に格納することにより、以降の処理でこのフォーマットを使用できるようにします。

Formatterの引数には、ログの形式を文字列として指定しますが、その中で使用できる表現には、主に以下のようなものがあります。

表現 内容
%(levelname)s ログレベル
%(asctime)s 実行時刻
%(message)s ログメッセージ
%(filename)s 実行しているプログラムのファイル名
%(name)s 実行している関数の名称

従って、上記コードで設定したフォーマットは、「[ログレベル] 実行時刻 ログメッセージ」という形式を意味します。

④ログ用ハンドラーの生成とフォーマットの適用

続いて、ログ用ハンドラーを生成し、さらに、③で生成したログフォーマットをそれに紐付けます。

~省略~
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
formatter = logging.Formatter('[%(levelname)s] %(asctime)s %(message)s')

stream_handler = logging.StreamHandler() #追加
stream_handler.setFormatter(formatter) #追加
~省略

コンソールにログを出力する際には、StreamHandlerというハンドラーを生成しますが、そのためには、loggingモジュール内の「StreamHandler」というメソッドを使用します

なお、ファイルにログを出力したい場合は、「FileHandler」というメソッドで対応するハンドラーを生成することができます。

また、生成したハンドラーに対するログフォーマットの紐付けは、ハンドラーの「setFormatter」メソッドを用いて行います。

⑤Loggerインスタンスへハンドラーを紐付け

さらに、生成したログ用ハンドラーを①で生成したLoggerインスタンスに紐付けることにより、ハンドラーを使用できるようにします。

~省略~
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
formatter = logging.Formatter('[%(levelname)s] %(asctime)s %(message)s')

stream_handler = logging.StreamHandler()
stream_handler.setFormatter(formatter)

logger.addHandler(stream_handler) #追加
~省略

紐づけは、「Loggerインスタンス.addHandler(ハンドラー)」という記述で行うことができます。

⑥ログの出力

最後に、ログを出力したい箇所に、出力用のコードを記述します。

出力用のコードは、「Loggerインスタンス.ログレベル(メッセージ)」という形式で記述します

例えば、「処理開始」というメッセージを、ログレベルINFOで出力したい場合、「logger.info(‘処理開始’)」と記述します。

さて、今回作成するプログラムでは、以下の箇所でログを表示するようにします。

タイミング ログレベル 表示するメッセージ
処理の開始時 INFO 「処理開始」
処理の終了時 INFO 「処理終了」
現物取引API固有のエラー発生時 ERROR ・「現物取引APIの異常発生」
・レスポンスの内容

これを実装するため、プログラムには以下のように4箇所、コードを追記します。

~省略~
logger.addHandler(stream_handler)

logger.info('処理開始') #追加
params = {
~省略~

response = requests.post('https://api.zaif.jp/tapi', data=encoded_params, headers=headers)
response_dict = json.loads(response.text)
if(response_dict["success"]) == 0:
    logger.error("現物取引APIの異常発生") #追加
    logger.error(response_dict) #追加

logger.info('処理終了') #追加
#print(response.text)

テスト実行

それでは、作成したプログラムが正しく動作するか、実際に実行して確認してみましょう。

なお、第13回のプログラムをベースに修正を加えた今回のプログラムでは、発注数量が極端に大きいため、資金不足という、現物取引API特有のエラーが発生します。

したがってプログラムを実行すると、4つのログ全てが出力されるはずです。

実際に実行した結果は以下の通りとなり、前回例示したログと同様のログがコンソールに出力されます。

終わりに

前回と今回の2回でログ出力の方法を解説しましたが、これによりbot稼働中の動作状況をリアルタイムで把握することが可能となりました。

ここまでの知識でbotの作成には十分移れるのですが、いざプログラムを作成しようと思うと、HTTPリクエストをサーバに投げる処理が複数個所に出てくるため、プログラムが少々複雑になります。

そこで次回は、共通的な処理を一か所にまとめて記載するための、処理のメソッド化について紹介したいと思います。

カテゴリ:フィンテック
<スポンサーリンク>

シェアする

フォローする