ルモーリン
ホーム 更新 Perl ランドナー サービス 雑談 コースガイド 鉄ゲタ 自転車 Linux リンク 連絡先

漢字でコンソール出力

2019-02-22

現象

Mojoliciousのモードが「development」で、 コントローラーの中から「$self->app->log->debug("たこルカは俺の嫁")」とやって、 ディレクトリ「log」がない場合はコンソールに表示されます。 ところがWindowsでは文字化けします。

原因

Mojo::Logのソースを読むと決め打ちでutf8でエンコードしているのが分かりました。 Windowsのコンソールはcp932なので文字化けする訳です。

コード

ディレクトリpluginを作成して、プラグインLogEncode.pmを作ります。 このモジュールはstartupで読み込みます。 ファイル出力時はutf8にエンコードしてコンソール出力時は環境に合わせた文字コードにエンコードします。
package LogEncode;
use Mojo::Base "Mojolicious::Plugin";
 
use Carp 'croak';
use Encode::Locale;
use Fcntl ':flock';
use Sub::Install;

sub register {
	my ($self, $app, $conf) = @_;

	Sub::Install::install_sub({
		code => sub {
			my ($self, $msg) = @_;
 
			return unless my $handle = $self->handle;
			flock $handle, LOCK_EX;
			if ($self->path) {
				$handle->print(Encode::encode 'UTF-8' => $msg) or croak "Can't write to log: $!";
			} else {
				$handle->print(Encode::encode console_out => $msg) or croak "Can't write to log: $!";
			}
			flock $handle, LOCK_UN;
		},
		into => "Mojo::Log",
		as => "append",
	});

	$app->log->debug("漢字対応ログ");
}

1;

自作プラグインをロード

アプリケーションのstartupの中で実行します。
	# 自家製プラグインをロード
	push @{$self->plugins->namespaces}, "Myapp::Plugin";

	# アルファベット順なのでログのエンコード出力プラグインが最初にロードされる
	$self->log->debug("----------");
	$self->log->debug("load plugin:");
	my $is_encode = "plugin";
	for (sort grep {/\.pm$/} $self->app->home->child("plugin")->list_tree->each) {
		my $pluginname = $_->basename;

		$pluginname =~ s/\.pm$//i;
		$self->app->log->debug("$is_encode: $pluginname");
		$self->plugin($pluginname);

		$is_encode = "プラグイン";
	}

	$self->log->debug("----------");

実行例

[2019-02-22 21:19:22.06035] [16943] [debug] ----------
[2019-02-22 21:19:22.06047] [16943] [debug] load plugin:
[2019-02-22 21:19:22.06179] [16943] [debug] plugin: LogEncode
[2019-02-22 21:19:22.06578] [16943] [debug] 漢字対応ログ
[2019-02-22 21:19:22.06596] [16943] [debug] プラグイン: MyAccount
[2019-02-22 21:19:22.09713] [16943] [debug] プラグイン: PpDateStamp
[2019-02-22 21:19:22.25559] [16943] [debug] プラグイン: PpDirectory
[2019-02-22 21:19:22.25663] [16943] [debug] プラグイン: PpDownload
[2019-02-22 21:19:22.25747] [16943] [debug] プラグイン: PpDraft
[2019-02-22 21:19:22.25829] [16943] [debug] プラグイン: PpGoogleMap
[2019-02-22 21:19:22.25908] [16943] [debug] プラグイン: PpPagedate
[2019-02-22 21:19:22.26018] [16943] [debug] プラグイン: PpParser
[2019-02-22 21:19:22.26116] [16943] [debug] プラグイン: PpPassPhrase
[2019-02-22 21:19:22.27845] [16943] [debug] プラグイン: PpRemark
[2019-02-22 21:19:22.27929] [16943] [debug] プラグイン: PpSourceCode
[2019-02-22 21:19:22.28017] [16943] [debug] プラグイン: PpTable
[2019-02-22 21:19:22.28146] [16943] [debug] プラグイン: PpTemplate
[2019-02-22 21:19:22.28247] [16943] [debug] プラグイン: PpTitle
[2019-02-22 21:19:22.28336] [16943] [debug] プラグイン: PpUpdate
[2019-02-22 21:19:22.28451] [16943] [debug] プラグイン: PpWrap
[2019-02-22 21:19:22.28532] [16943] [debug] プラグイン: QuoteLessDumper
[2019-02-22 21:19:22.28681] [16943] [debug] {
  dumper => "漢字を表示"
}

[2019-02-22 21:19:22.28691] [16943] [debug] ----------