python3のloggerでミリ秒を使う、他
ブログスモールスタート第2段。
最近pythonの勉強を始めて、
ロギングには標準モジュールのlogging.loggerを使え!ってのはわかったのだけど色々苦労したのでその辺をメモ。
へなちょこエンジニア(コピペプログラマー)レベルなので、Python初学者で詰まってる人には参考になるかもしれない。
loggerとは
基礎的なところは公式ドキュメントを参照>Logging HOWTO — Python 3.6.5 ドキュメント
まあ一応ざっっっくり説明しておくと、
- logging.loggerをセット(ログの取得元を設定)
- handlerをセット(出力先を設定)
- loggerにhandlerをセット(紐づけ)
- print('debug: hogehoge')していたところを、logger.debug('hogehoge')に変える
- logger.error('hogehoge!!')みたいに重要度でレベル分けできる
といった感じで使える。
loggerに対してhandlerを複数セットしたりできるので、標準出力とファイル出力同時にするのも簡単。
フォーマッタでミリ秒/ナノ秒を使いたい
handlerに対しては、formatterを設定できる。
デフォルトだと(asctimeに対して)%Y-%m-%d %H:%M:%S
形式がセットされているので、
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
だと
2005-03-19 15:10:26,618 - simple_example - DEBUG - debug message
みたいに返ってくる(公式ドキュメントから引用)。
この日付形式に不満がなければそのままでもいいのだけれど、1984/01/24 17:00:56.999
形式にしたい。
最初にドキュメントとかを見てdatefmtにstrftimeの形で指定してあげればいいっぽいので次のコードにしたがエラー。
logging.Formatter('%(asctime)s [%(levelname)][%(name)s] %(message)s',datefmt='%Y/%m/%d %H:%M:%S.%f')
%fがだめらしい。 ※今ドキュメントよく見たらpython3.6のstrftimeに%fない?…2.xの方の情報見てたかな
解決法:次のコードを使う
logging.Formatter('%(asctime)s.%(msecs)-3d [%(levelname)-7s][%(name)s] %(message)s',datefmt='%Y/%m/%d %H:%M:%S')
datefmtでは秒まで。(msecs)でナノ秒が取れるので、それを左揃え3桁パディングしてあげればミリ秒が取れる。
独自のLogRecord属性
ログに関数IDや処理中ファイルみたいなのを出したい場合、
これをいちいちlogger.info('[XX-YY-Z001] hogehoge with [sample.csv]')
とか
functionId = 'XX-YY-Z001' filePath = 'sample.csv' …(略)… msg = '[{0}] hogehoge with [{1}]'.format(functionId,filepath) logger.info(msg)
としてもいいけど、書式がズレないように気を使うのがめんどくさいし、
途中で書式変えたくなった時死ぬほどめんどくさい。絶対ヤダ。
というわけで色々調べると、extraオプションで独自設定ができるらしい。
logging.Formatter('%(asctime)s.%(msecs)-3d [%(levelname)-7s] [%(functionId)s] %(message)s with [%(file)s]',datefmt='%Y/%m/%d %H:%M:%S')
みたいに、LogRecord属性にない(functionId),(file)をフォーマッタ時点で入れておく。
logger呼出時に、logger.info('hogehoge',extra={'functionId':'XX-YY-Z001','file':'sample.csv'})
とか
functionId = 'XX-YY-Z001' filepath = 'sample.csv' ex = {'functionId':functionId,'file':filepath} …(略)… logger.info('hogehoge',extra=ex)
してあげれば(extra引数に辞書形式で渡してあげれば)OK。
ただしこのやり方だと、logger呼出時に(functionId)や(file)がないとか、extraオプション自体がないとエラーになってしまうのでそれはそれでめんどくさい。
LogAdapterとやらをなんとかすれば解決できそうな気がするけど、とりあえず現状はここまで。
実際に書いたコード的なもの
適当に改変してるけど大体上記のことを反映したlogger生成関数。
def set_logger(): from logging import (getLogger,StreamHandler,FileHandler,Formatter, DEBUG,INFO,WARNING,ERROR) from datetime import datetime as dt import os # const的ななにか LOGLEVEL = 'DEBUG' BASEPATH = os.path.dirname(os.path.abspath(__file__)) # パス、ファイル名設定 LOGPATH = BASEPATH + '/log/system_' + dt.now().strftime('%Y%m%d') + '.log' # logger設定 logger = getLogger(__name__) logger.setLevel(LOGLEVEL) # handler設定 # フォーマット設定 handler_format = Formatter('%(asctime)s.%(msecs)-3d' + ' [%(levelname)-7s] [%(functionId)s]' + ' %(message)s with [%(file)s]', datefmt='%Y/%m/%d %H:%M:%S') # 標準出力 stream_handler = StreamHandler() stream_handler.setLevel(LOGLEVEL) stream_handler.setFormatter(handler_format) # ファイル出力 file_handler = FileHandler(LOGPATH,'a',encoding='utf-8') file_handler.setLevel(LOGLEVEL) file_handler.setFormatter(handler_format) # loggerにhandlerセット logger.addHandler(stream_handler) logger.addHandler(file_handler) return logger # 呼出時 functionId = 'XX-YY-Z001' filepath = 'sample.csv' ex = {'functionId':functionId,'file':filepath} logger.info('hogehoge',extra=ex)
メモ:youtube-dlで1080p
作ったはいいが使ってなかったブログを真面目に始めよう、でもめんどくさいしな…
というわけでスモールスタート(?)していく。
--目次--
youtube-dlで1080p動画を手に入れる
youtube-dlで1080p動画の落とし方がわからなかった&情報が少なかったので備忘録兼ねて書いておく。
youtube-dl自体の導入とかは省略。なお執筆時の環境はMacOS 10.13.5+Python2.7.10+youtube-dl 2018.06.25。
そもそもyoutube-dl <URL or ID>
すると、勝手に最高画質を落としてくれるんだけど、
このときの最高=720pということらしい。
※公式Webプレーヤー上で1080pあることが確認できる動画でも720pになる。
1080pで落としたければformatを指定してあげる必要がある。
→ ちょっと手順を簡単にするpythonスクリプトを書いて記事にしたのでそちらもどうぞ
Youtube-dlで1080p動画ダウンロード手順を簡略化するスクリプトを書いた - あくぽろぐ aqpolog
やり方
youtube-dl <URL or ID> --list-formats
すると対象動画のフォーマット一覧が表示される。
hogehoge:~ aqpolo$ youtube-dl --list-formats unmG7ewXE1M [youtube] unmG7ewXE1M: Downloading webpage [youtube] unmG7ewXE1M: Downloading video info webpage [info] Available formats for unmG7ewXE1M: format code extension resolution note 249 webm audio only DASH audio 54k , opus @ 50k, 610.70KiB 250 webm audio only DASH audio 72k , opus @ 70k, 805.79KiB 140 m4a audio only DASH audio 127k , m4a_dash container, mp4a.40.2@128k, 1.62MiB 171 webm audio only DASH audio 135k , vorbis@128k, 1.48MiB 251 webm audio only DASH audio 145k , opus @160k, 1.57MiB 278 webm 256x144 144p 105k , webm container, vp9, 30fps, video only, 1.06MiB 160 mp4 256x144 144p 111k , avc1.4d400c, 30fps, video only, 827.60KiB 242 webm 426x240 240p 222k , vp9, 30fps, video only, 1.94MiB 133 mp4 426x240 240p 245k , avc1.4d4015, 30fps, video only, 1.58MiB 243 webm 640x360 360p 407k , vp9, 30fps, video only, 3.54MiB 134 mp4 640x360 360p 634k , avc1.4d401e, 30fps, video only, 4.32MiB 244 webm 854x480 480p 754k , vp9, 30fps, video only, 6.31MiB 135 mp4 854x480 480p 1165k , avc1.4d401f, 30fps, video only, 8.51MiB 247 webm 1280x720 720p 1500k , vp9, 30fps, video only, 12.88MiB 136 mp4 1280x720 720p 2339k , avc1.4d401f, 30fps, video only, 16.42MiB 302 webm 1280x720 720p60 2647k , vp9, 60fps, video only, 21.64MiB 248 webm 1920x1080 1080p 2736k , vp9, 30fps, video only, 23.87MiB 298 mp4 1280x720 720p60 3474k , avc1.4d4020, 60fps, video only, 28.83MiB 137 mp4 1920x1080 1080p 4400k , avc1.640028, 30fps, video only, 31.06MiB 303 webm 1920x1080 1080p60 4434k , vp9, 60fps, video only, 39.12MiB 299 mp4 1920x1080 1080p60 5788k , avc1.64002a, 60fps, video only, 52.93MiB 17 3gp 176x144 small , mp4v.20.3, mp4a.40.2@ 24k, 1000.05KiB 36 3gp 320x180 small , mp4v.20.3, mp4a.40.2, 2.72MiB 18 mp4 640x360 medium , avc1.42001E, mp4a.40.2@ 96k, 7.64MiB 43 webm 640x360 medium , vp8.0, vorbis@128k, 9.68MiB 22 mp4 1280x720 hd720 , avc1.64001F, mp4a.40.2@192k (best)
こんな感じでaudioとvideoそれぞれ解像度やコーデック別に出てくる。※(best)が付いている22番が自動時の最高画質(720p)
目的のformat-codeを次のように指定してあげれば良い。
youtube-dl <URL or ID> -f 299+140 --merge-output-format mp4
これでうまくいく、かと思いきや生成されたファイルがaudioとvideoで別々になってしまった。
どうやら--merge-output-formatは場合によってffmpegかavconvが必要らしい。
ffmpegを入れて再実行したら無事に目的の1080p動画が出来上がった。
※この辺の画面出力はメモし忘れたので省略
hogehoge:~ aqpolo$ youtube-dl -f 299+140 --merge-output-format mp4 unmG7ewXE1M [youtube] unmG7ewXE1M: Downloading webpage [youtube] unmG7ewXE1M: Downloading video info webpage [download] Destination: 「ACE COMBAT(TM) 7 - SKIES UNKNOWN」E3 2018出展用トレーラー-unmG7ewXE1M.f299.mp4 [download] 100% of 52.93MiB in 00:02 [download] Destination: 「ACE COMBAT(TM) 7 - SKIES UNKNOWN」E3 2018出展用トレーラー-unmG7ewXE1M.f140.m4a [download] 100% of 1.62MiB in 00:00 [ffmpeg] Merging formats into "「ACE COMBAT(TM) 7 - SKIES UNKNOWN」E3 2018出展用トレーラー-unmG7ewXE1M.mp4" Deleting original file 「ACE COMBAT(TM) 7 - SKIES UNKNOWN」E3 2018出展用トレーラー-unmG7ewXE1M.f299.mp4 (pass -k to keep) Deleting original file 「ACE COMBAT(TM) 7 - SKIES UNKNOWN」E3 2018出展用トレーラー-unmG7ewXE1M.f140.m4a (pass -k to keep)
うまくいくと上の感じで映像と音声が結合されたmp4がgetできる。
今回はここまで。
参考URL
公式のREADME
github.com
日本語でのオプションまとめ
d.hatena.ne.jp
えーすこんばっとせぶん
www.youtube.com