Shogo's Blog

Apr 10, 2018 - 2 minute read - hugo go golang

OctopressからHugoに乗り換えた

OctopressからHugoに乗り換えました。 以下のような理由からです。 Rubyの環境をメンテナンスし続けるのが面倒 最近Octopress自体の更新が滞っている ビルド時間が長い 一番最初の理由が大きくて、いつもビルドしていた環境を壊してしまって修復が面倒になってしまいました。 そこでようやく重い腰を上げて移行したというわけです。 移行手順 OctopressからHugoへの移行は先人たちがたくさんいるので、それを参考にします。 # 記事のコピー cp octopress-site/source/_posts/* hugo-site/content/post/ # 画像のコピー cp -r octopress-site/source/images/* hugo-site/static/images/ # 記事のタイムスタンプの形式を変える # Hugoでは、"2016-09-25T15:09:57"のような形式のタイムスタンプでないとパースに失敗します find . -type f -exec sed -i "" -e 's/date: \([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\) \([0-9]\{2\}:[0-9]\{2\}\)$/date: \1T\2:00+09:00/g' {} \; パーマネントリンクを維持するために OctopressからHugoへ移行する方法 のRubyスクリプトを利用させていただきました。 dir = 'content/post/' Dir::foreach(dir) do |filename| if filename =~ /\.markdown$/ slug = filename.gsub(/\d{4}-\d{2}-\d{2}-/, '').sub('.markdown', '') puts "#{filename} : #{slug}" lines = [] File::open(dir + filename) do |f| f.each do |line| lines << line end end File::open(dir + filename, 'w') do |f| lines.

Jan 2, 2018 - 1 minute read - mackerel

Mackerel AWS Integration 用の CloudFormation テンプレートを書いた

昨年の年末から Mackerel の本格導入を始めました。 それに当たって AWS Integration 用の CloudFormation テンプレートを書いたので、 他のプロジェクトでも導入が簡単になるよう公開しました。 shogo82148/cf_mackerel 使い方 GitHub Pages でテンプレートを公開しているので、 template-body にテンプレートのURLを指定して、 新しいスタックを作成するだけです。 aws cloudformation create-stack --stack-name "MackerelIntegrationIamUser" \ --template-body https://shogo82148.github.io/cf_mackerel/mackerel.yaml \ --capabilities CAPABILITY_NAMED_IAM 新しい名前付きIAMロールを作成するので CAPABILITY_NAMED_IAM が必要です。 作成がうまくいくとOutputに以下のようなARNが出力されるので、 MackerelのAWS Integrationの設定画面へ入力しましょう。 arn:aws:iam::xxxxxxxxxxxx:role/MackerelAWSIntegrationRole-ap-northeast-1 ロール名について ロール名が意図せずに変わってしまって連携が切れてしまうのを防ぐため、 ロール名は決め打ちです。 MackerelAWSIntegrationRole-ap-northeast-1 ロール名にリージョン名(この場合は ap-northeast-1)が含まれていますが、 作成されたロールはグローバルなリソースなので、他のリージョンでも使用可能です。 わざわざリージョン名含めているのは CloudFormation の警告にしたがったためです。 警告 IAM リソースに名前を付けると、複数のリージョンで同じテンプレートを再利用した場合に、回復不能なエラーが発生する場合があります。 これを防止するために、Fn::Join と AWS::Region を使用して、次の例のように地域固有の名前を作成することをお勧めします RoleName 回復不能なエラー!! コワイので実際に何が起こるかは試してませんが、警告には素直に従っておくことにします。 参考 AWS::IAM::Role - AWS CloudFormation - mackerelのAWSインテグレーション用IAM Userをcloudformationで作る Tomohiro/tf_mackerel 同じことをするTerraformのモジュール

Dec 6, 2017 - 2 minute read - aws-lambda python mecab

MeCabをAWS Lambdaで動かす(2017年版)

AWS Lambda上で鯖(Mackerel)の曖昧性問題を機械学習で解決しようの記事の中で、 Lambda上でMeCabを動かすことについて以下のように触れられています。 日本語を扱う自然言語処理ではMeCabを扱うことが多いですが、Lambda上でMeCabを動かすのは一手間必要なようです。 確かにLambda上でMeCabを動かすのは一手間必要です。 しかし、参照している記事は少し古くて、今はもう少し手軽にできるようになっています。 ブコメでも言及しましたが、改めて記事として残しておこうと思います。 ビルド方法(2017年版) 結論から言うと Norio Kimura さんのコメント 通りにビルドするのが、2017年12月現在一番楽な方法です。 (お返事すっかり忘れていてスイマセン・・・情報提供ありがとうございます) 調べてみると、AWS Lambda では環境変数 LD_LIBRARY_PATH が既に設定されていて /var/task/lib を含んでいました。元記事で ./configure –prefix=$PROJECT_HOME/local ではなく ./configure –prefix=$PROJECT_HOME とすればライブラリとの動的リンクは何もしなくても実現できます。さらにコードが展開されるディレクトリ /var/task を固定値だと決め打ちして PROJECT_HOME を /var/task にして開発すれば MeCab に渡すパラメーターの設定(-d, -r)も不要になります。undocumented な仕様に2つも依存していて気持ち悪いですが、MeCab を呼ぶ側のコードを Lambda 用に変更する必要がなくなります。 コメント中の元記事というのは、こちらの記事のことです。 AWS Lambda で MeCab を動かす export PROJECT_HOME=/var/task # LAMBDA_TASK_ROOT # 1. プロジェクト用にディレクトリを作成 mkdir -p "$PROJECT_HOME" # 2. MeCabのダウンロードとインストール # googlecodeサービス終了に伴い、ダウンロードURLが元記事と変わっていることに注意 cd "$HOME" curl -fsSL "https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7cENtOXlicTFaRUE" -o mecab.tar.gz cd mecab-0.996 .

Oct 28, 2017 - 2 minute read - go golang

Go言語の浮動小数点数のお話

元ネタ: [JavaScriptの問題] var a = 0.3 - 0.2; var b = 0.2 - 0.1; var c = a==b; cの中身はどれ? — RAO(らお)@けもケP-31 (@RIORAO) 2017年10月24日 正確な実数計算をやらされるJavaScriptくん #擬竜戯画 pic.twitter.com/ipE56C2YbV — RAO(らお)@けもケP-31 (@RIORAO) 2017年10月26日 コンピューターで浮動小数点数を扱ったことのある人なら一度は経験する、 数学上の計算とコンピューター上の計算が合わない計算の一例ですね。 この件に関して、Go言語では正しく(=数学的な結果と同じように)計算できるとの情報が。 おそらくGoはコンパイラがa=0.1とb=0.1に変換していると思われます。 添付した画像のコードだとtrueになりますが、constをvarに変更するとfalseになります。constはコンパイル時に計算されますが、varは実行時に計算されるためです。 pic.twitter.com/LpKZF2kOjH — morikuni (@inukirom) 2017年10月27日 しかしながら、inukiromさんのこの推察、半分はあってますが、半分は間違っていると思います。 なぜGo言語でこのような結果になったのか、検証してみました。 Goの数値定数の型について 以前Go言語でコンパイル時フィボナッチ数列計算で紹介した Better C - Go言語と整数 #golangにもあるように、 Goの定数には「型がない(場合がある)」「任意の精度で計算してくれる」という特徴があります。 このため、普通はどう考えてもオーバーフローしそうなこんな演算も・・・ package main import ( "fmt" ) func main() { var i uint64 = 31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679 % 1000000007 fmt.Println(i) } play.golang.org/p/FkMVpY2Fa3 型がない定数同士の演算は 162132938 と正しい答えを出してくれます。

Oct 22, 2017 - 2 minute read - go golang

ACMのドメイン検証をシミュレートするやつ書いた

始まりは一件のメールから。 Title: Action Required - Your certificate renewal Greetings from Amazon Web Services, You have an AWS Certificate Manager (ACM) provided SSL/TLS certificate in your AWS account that expires on Nov 04, 2017 at 12:00:00 UTC. That certificate has the following domains: example.com, *.example.com AWS account ID: xxxxxx AWS Region name: us-east-1 Certificate identifier: arn:aws:acm:us-east-1:xxxxxx:certificate/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Therefore, ACM has initiated the process to renew this certificate. You must take the action below before Nov 04, 2017 at 12:00:00 UTC to avoid certificate expiration, which might cause your website to become unreachable.

Aug 25, 2017 - 2 minute read - perl

Perl 5.26 & Unicode 9.0 で変わる書記素クラスタ(grapheme cluster)のお話

WEB+DB PRESS Vol.100が発売されましたね。 記念すべき Vol.100 おめでとうございます! WEB+DB PRESS の連載「Perl Hackers Hub」今回のテーマは「【第46回】Perl 5.26で変わること」です。 Perl 5.26 で追加になった機能、アップグレードの際に気をつけなければならないところ( 特に @INC 問題とか )などに触れられているので、 Perl Monger の方はぜひ読むとよいと思います。 追加された機能のひとつとして Unicode 9.0 サポートが挙げられているのですが、以下のような簡単な紹介に留まっています。 Unicode 9.0にはオリンピックで活躍するであろう金銀 銅メダルの絵文字などが追加されました。 Unicode 9.0 で変わるのはそれだけではありません! Unicode 9.0 での 書記素クラスタ(grapheme cluster) の扱いを少し前に調査したので紹介します。 書記素クラスタ(grapheme cluster)とは 書記素クラスタ(grapheme cluster)とは、人間にとって自然な1文字を表すものです。 たとえば “é” という文字は一見1文字に見えますが、 length で文字数をカウントすると2文字としてカウントされます。 $ perl -Mutf8 -E 'say length "é"' 2 これは length がUnicodeのコードポイント数を数えており、 “é"が"e”(U+0065) + アクセント記号(U+0301) の2つのコードポイントで構成されているためです。 他にも異字体セレクタというのがあったり、 絵文字シーケンスというのがあったりして、 コードポイントの数=文字数とは限りません。 これらの文字たちを1文字として数えるための概念が書記素クラスタ(grapheme cluster)です。 Unicode 9.0での変更点 Unicode 8.

Jun 26, 2017 - 4 minute read - go golang time leapsecond

Go1.9から使える Monotonic Clocks を試してみた

先日Go1.9beta1がリリースされました。 Go 1.9 Beta 1 is released! Announcement:https://t.co/lV5nvXwOoR Get it!https://t.co/2LhlOo2EtX#golang pic.twitter.com/zm09DwX93q — Go (@golang) 2017年6月14日 Go 1.9 Release Notes 型エイリアスのサポート、math/bitsパッケージ、 sync.Map型など、 今回のアップデートでも便利そうな機能が追加されます。 詳しくはtenntennさんのGopher Fest 2017参加レポートをどうぞ。 今回のリリースノートを見て、個人的に注目しているのはMonotonic Clocksのサポートです。 他の機能追加はTwitterとかで見かけるけど、 Monotonic Clocksはなぜかあまり見ない・・・。 beta1がでて手軽に試せるようになったので、試してみました。 Monotonic Clocks Go1.8以前で取得していた時刻は「wall clock」といい、現在の正しい時刻を知るために使います。 一方「monotonic clock」は、時間を計るために使うものです。 Go1.9からはtime.Nowで取得できる時刻に「wall clock」と「monotonic clock」が含まれるようになります。 timeパッケージのドキュメントから コード片を引用します。 t := time.Now() ... operation that takes 20 milliseconds ... u := time.Now() elapsed := t.Sub(u) 上のコードで elapsed は 20ms となるはずですが、 実際はそうはならないケースがあります。 具体的には以下のようなケースです。 ntpdなどによってOSの時刻が変更された場合 うるう秒が挿入・削除された場合 Go1.9からはこのようなケースでも正しく時間を計ることができます。 うるう秒を入れてみた うるう秒が入ったときの挙動が気になったので実際にやってみました。 セットアップが簡単になるようNICTのPerl版SNTPのGolangポートを作ったので、 それを使って偽物のうるう秒を挿入してみます。

Jun 16, 2017 - 4 minute read - go golang mysql

ぼくのかんがえたさいきょうのcontext対応版go-mysql-driverをマージしてもらった

go-sql-driverにcontext.Context対応するプルリクエスト go-sql-driver/mysql#608 を送って取り込んでもらいました!! 現時点ではまだ正式リリースされていませんが、次のリリース(version 1.4)から使えるようにはずです。 masterブランチではすでに使えるようになっているので、引き続き人柱募集中です。 コネクションプーリングを実装していて、自分も「context.Contextサポートしたい!」というかたのために、 実装の概要をメモとして残しておきます。 おおまかな仕組み 「contextの監視のみを行うgoroutine(以下、watcher goroutine)」をあらかじめ起動しておく 「やりたい処理を実際に実行するgoroutine(以下、executor goritune)」とchannelを経由してcontext.Contextをやり取りする watcher goroutineがこの実装で一番重要な部分です。 watcher goroutine の実装 一番重要な watcher goroutine の実装例から見てみましょう (実際には細かい最適化などが入るため、マージされたコードとは異なります)。 func (mc *mysqlConn) startWatcher() { // executor goritune と `context.Context` のやり取りをするための channel watcher := make(chan context.Context, 1) mc.watcher = watcher // executor goritune で処理が完了したことを知るための channel finished := make(chan struct{}) mc.finished = finished // コネクションがCloseされたことを知らせるための channel mc.closech = make(chan struct{}) // ここから watcher goroutine 本体 go func() { for { // executor goritune から `context.

May 30, 2017 - 3 minute read - go golang

Re: GoとPythonとGrumpyの速度ベンチマーク

GoとPythonとGrumpyの速度ベンチマーク ~Googleのトランスパイラはどれくらい速い?~という記事を拝読したのですが、 もう一歩踏み込んで検証して欲しい・・・。 並列処理性能が優れているほか、PythonコードからGoのパッケージをPythonモジュールのように呼び出して利用することもできるという特徴がある。 とGoogle、すごくスケールするPython実行環境をGoで開発から引用しているのに、 この件に全く触れていないんですよね。 Twitterに呟いたってどうせ誰もやってくれない気がするので、自分で試してみました。 環境 この記事を書いている2017年5月30日現在の最新バージョンで検証しました。 go version go1.8.3 darwin/amd64 CPython 2.7.13 Grumpy d8d01899f5 Grumpyのインストール方法はREADMEにある通り。 make export GOPATH=$PWD/build export PYTHONPATH=$PWD/build/lib/python2.7/site-packages ただ個人的な環境問題としてPythonのバージョン管理に利用しているpyenvとの相性が悪いらしく、 pyenvが管理しているPythonへのパスを直接通す必要がありました。 (これがないとPythonスクリプトがなぜかbashに処理される。なんかこの問題最近Twitterで見たような・・・) export PATH=$HOME/.pyenv/versions/2.7.13/bin:$PATH モンテカルロ法を並列実行してみる まず、並列処理性能について検証してみましょう。 モンテカルロ法の各試行は独立しているので、並列実行にするのは容易です。 Python2のthreadingモジュールを使って並列実行してみましょう。 コード #coding:utf-8 # モンテカルロ法 Pure Python 並列版 import threading import random import sys class MyThread(threading.Thread): def __init__(self): super(MyThread, self).__init__() self.c = 0 def run(self): r = random.Random() c = 0 for _ in xrange(num): x = r.random() y = r.

May 4, 2017 - 3 minute read - go golang

String::RandomのGo移植を書いてみた

golangkyotoでString::RandomのGo移植についての発表があったと聞き、 これに対抗して以前途中まで書いていたString::RandomのGo移植をちょっといじって公開しました。 shogo82148/go-rerand 背景 ナイーブな実装の問題点 実はgolangkyoto以前にもGoの正規表現エンジンを使ってランダムな文字列を生成する試みはあって、 たしかにこれは面白そうだと記事を読んでいました。 「Goの正規表現エンジンを使ってファジング用ツールを書いてみる」 しかし、gocha同様、この実装では文字列の長さが幾何分布に従うため、短い文字が多めにでてしまいます。 % gocha -n 100000 'a*' | sort | uniq -c 50054 24894 a 12633 aa 6278 aaa 2994 aaaa 1517 aaaaa 809 aaaaaa 400 aaaaaaa 206 aaaaaaaa 109 aaaaaaaaa 54 aaaaaaaaaa 22 aaaaaaaaaaa 15 aaaaaaaaaaaa 7 aaaaaaaaaaaaa 4 aaaaaaaaaaaaaa 3 aaaaaaaaaaaaaaa 1 aaaaaaaaaaaaaaaa 正規表現のパターンを数え上げとその問題点 この問題を解決するために 「この先何パターンあるかを調べておけば、正規表現が表す文字列の集合からランダムに文字列を取り出せるのでは?」 と考え、golangkyoto以前からちょこちょこ実装を進め、不完全ながらも一応動作するところまでは書いていたのです。 有向グラフの経路数えあげ問題なので、メモ化再帰を使って頑張れば解けます。 少々面倒ですが、おねえさんの問題と比べれば簡単です。 パターンを数え上げる都合上、組み合わせが無限にある a* ような正規表現は扱えません。 a{1,10} のように明示的に範囲を指定する必要があります。 たとえば a{1,10} は10パターン組み合わせがあるので、20万個ランダムに生成すると、それぞれのパターンがおおよそ2万個ずつ生成されます。 (-d オプションについては後述) $ rerand -d -n 200000 'a{1,10}' | sort | uniq -c 20153 a 19863 aa 19899 aaa 19908 aaaa 19975 aaaaa 20000 aaaaaa 20081 aaaaaaa 20021 aaaaaaaa 20072 aaaaaaaaa 20028 aaaaaaaaaa [ab]{1,3}のような正規表現でも、それぞれのパターンがおおよそ同じ数だけ生成されます。