前回の記事に引き続き、今回も仮想通貨botの開発状況をまとめていきます。
今回は、こちらの記事を参考にして「botの稼働状況を監視する」をテーマに学習を進めていきます。
やることは「ログをファイルに書き出す」「そのファイルをメールで送る」です。
下準備
まずは、前回設定した外部サーバーにccxtライブラリをインポートします。
参考にしたのは、こちらの記事です。
この作業は特に問題なくサクサク進みました。
すでに作成していた三兵のコードも問題なく稼働しています。
指し値注文から約定までも正常に稼働しています。(ここでは損失を出していますが)
ログをファイルに書き出す
実行したコードは以下の通り。赤字の部分は個人情報が入っているので伏せます。
import time
from logging import getLogger, Formatter, StreamHandler, FileHandler, INFO
logger = getLogger(__name__)
handlerSh = StreamHandler()
handlerFile = FileHandler("/Users/ユーザー名/Downloads/bot/log.txt") # ファイルパスを変更
handlerSh.setLevel(INFO)
handlerFile.setLevel(INFO)
logger.setLevel(INFO)
logger.addHandler(handlerSh)
logger.addHandler(handlerFile)
while True:
logger.info("Hello!")
time.sleep(1)
ロギングとは「ログを出力すること」であり、ログとは「プログラムの実行中に起こった出来事」です。
2行目のコードでpythonの標準モジュールであるloggingを使用する下準備をしています。
from logging import getLogger, Formatter, StreamHandler, FileHandler, INFO
from~~import~~という書き方にしているのは「その後の記述をシンプルにするため」です。
このコードでは「loggongの中からgetLogger, Formatter, StreamHandler, FileHandler, INFOを使いますよ」という約束をしています。これを書いておくと、これ以降は省略した形でコードを書くことができて便利です。
また、今まではprint()で情報を出力していましたが、loggongモジュールを使うことでいくつかのメリットが得られることも併せて確認することができました。
loggingモジュールを使うことで得られるメリットは以下の通り。
- 情報の出力方法を切り替えられる(ユーザー目線の形式かログ出力か)
- ログの種類のレベル分けができる
- フォーマットを指定することで、出力の仕方を簡単に統一できる
参考
logging---Python 用ロギング機能←pythonのDocs。辞書的に使う。もっとも誤解の少ない理解が得られる。
【Python入門】loggingモジュールで処理の記録を残してみよう!
【Python】「from ~ import ~」 の使い方←「from~~import」という書き方にするメリットを解説している。
【良く分かる】Python loggerの 使い方と注意点←loggerの構造解説。
handlerとは?
次につまずいたのは「handler」。
今回のコードの中に出てくるのですが、これの意味も分からないので調べることにしました。
調べた結果、handlerはログの出力先を設定することに関連していることが分かりました。
参考
メールを送信する
メールを送信するのに使ったコードは以下の通り。
import smtplib
from email.message import EmailMessage
from datetime import datetime
with open( "log.txt")as file:
msg = EmailMessage()
msg.set_content(file.read())
msg["Subject"] = "bot稼働状況の通知:{}".format(datetime.now().strftime("%Y-%m-%d-%H-%M"))
msg["From"] = "メールアドレスを入力"
msg["To"] = "メールアドレスを入力"
server = smtplib.SMTP("smtp.gmail.com",587)
server.starttls()
server.login("GoogleアカウントのIDを入力","アプリケーション固有のパスワードを入力")#IDは通常メールアドレスでOK、アプリケーション固有のIDは別途生成が必要
server.sendmail( msg["From"],msg["To"],msg.as_string())
server.close()
メールで送るファイル名をwith open( "log.txt")as file:で指定しています。
赤字の部分を書き換えることで、ファイルを変更することができます。
ここでつまずいたのは、以下の部分。
server.login("GoogleアカウントのIDを入力","アプリケーション固有のパスワードを入力")
アプリケーション固有のパスワードの生成方法はこちらのサイトで解決できました。
コードを実行して、無事にメールの受け取りも確認することができました!
エラー解決をAIで行う
そもそも私が最初につまずいたのは、以下の部分でした。
handlerFile = FileHandler("/Users/ユーザー名/Downloads/bot/log.txt") # ファイルパスを変更
ファイルパスを入力してコードを実行してもエラーが発生するので、今回も原因調査。
調べてみてもイマイチ解決につながらないので、AIのコード修正してもらいました。
ChatGPTに出した指示は以下の通り。
以下のコードを実行したら〜〜(エラーメッセージをコピペ)というメッセージが表示された。解決方法を教えなさい。(以下、実行したコードをコピペ)
その結果、このエラーは「指定したファイルパスが既にディレクトリである」ために発生していることが分かりました。
FileHandlerは、指定されたパスにファイルを作成し、ログをそのファイルに書き込むことを試みますが、既存のディレクトリにはファイルを作成できなかったようです。
解決方法は、ファイルを保存するための適切なディレクトリを指定することでした。
ChatGPTが示したコードを入力することで、問題なくプログラムを実行することができるようになりました。
この方法で、他のエラーも解決することができています。
まとめ
今回は「枝葉の部分の調査に時間をかけてしまった」ということが反省点です。
確かにbotの稼働状況を監視するのは重要ではありますが、現段階では強いbotを作ることが最優先事項です。
自分で考えた戦略を実行するようになって初めて「監視」という手段が必要になるはずなのに、今回は手段の深掘りがメインになってしまいました。
Windowsタスクマネージャーで監視botの実行設定をすることは一旦保留にして、必要になったら再び扱うことにします。
次回の学習では「LINEに送信する」がテーマになりますが、技術面の理解をあまり深掘りしすぎることなくパパッと学習を実行を済ませてbot開発へと戻りたいです。
「理解を求めるあまり深掘りしすぎない」「大雑把な理解でも進めていく」
この2点を今後の教訓にします。
現在学習していることの本質と目的を見失わずに、コツコツと学習を継続していきます。