ホーム ブログ ページ 24

走れJMeter

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

 メロスは激怒した。必ず、かの30秒も掛かるAPIを高速化せねばならぬと決意した。メロスにはボトルネックがわからぬ。メロスは、クライアントエンジニアである。XCodeを使い、仮想iOSと遊んで暮して来た。けれどもボトルネックに対しては、人一倍に敏感であった。きょう未明メロスは電子の海を出発し、SSHで海外へ飛び、三千里はなれた此このシラクスのサーバーにやって来た。メロスには父も、母も無い。女房も無い。十六の、内気な二次元の妹と二人暮しだ。この妹は齢二十になるかの邪智暴虐の王を倒した勇者を花婿として迎える事になっていた。結婚式も間近かなのである。メロスは、それゆえ、泣きながらも仕事に励んでいたのだ。
 メロスには竹馬の友があった。セリヌンティウスである。今は此のシラクスのサーバーで、サーバーエンジニアをしている。その友を、これから不正に手にいれたroot権限で訪ねてみるつもりなのだ。久しく逢わなかったのだから、訪ねて行くのが楽しみである。歩いているうちにメロスは、サーバーの様子を怪しく思った。タイプがやけに重い。もう既に日も落ちて、あちらの時刻は暗いだろうけれども、全体が、やけに重い。のんきなメロスも、だんだん不安になって来た。セリヌンティウスの痕跡を発見し、何かあったのか、追跡した。二年まえに此のサーバーに来たときは、夜でもサーバーは穏やかで、軽かったはずだった。管理者からは中々その痕跡が分からなかった。メロスは両手でコマンドをゆすぶって追跡を重ねた。セリヌンティウスは、あたりをはばかるように、わずかながら痕跡を残していた。

#このAPIは、時間がかかっている

「なぜかかるのだ。」

//悪心を抱いている、というのですが、誰もそんな、悪心を持っては居りませぬ。ただ、コードがアレなだけです。

「たくさんのSQLをよんでいるのか。」

=begin
はじめはアクセスしたユーザーを。
それから、御自身の設定ファイルを。
それから、メモ化されていないマスタデータを。
それから、たくさんのユーザーデータを一つずつ参照して。
それから、新たに作成されるデータを念のため一つ一つバリデーションをかけて。
それから、キャッシュの更新を。
=end

「おどろいた。セリヌンティウスは乱心か。」

<!-- ユーザー数が急激に増えたことに加えて、仕様変更が重なったことが原因。
このごろは、それによってぐちゃぐちゃになったAPIそのものの振る舞いもおかしくなっている。
レスポンスが30秒を超えることも全くおかしくない。
-->

 コメントを読んで、メロスは激怒した。「呆れたAPIだ。生かして置けぬ。」
 メロスは、単純な男であった。アクセスログを残したままで、のそのそソースのディレクトリにはいって行った。たちまち彼は、問題のAPIを読んだ。調べて、メロスの脳裏からはデータベースにインデックスが貼られていない疑惑が出て来たので、胸騒ぎが大きくなってしまった。メロスは、セリヌンティウスに直接電話をした。
「このデータベースは何をするつもりであったか。言え!」暴君メロスは静かに、けれども威厳を以もって問いつめた。そのセリヌンティウスの顔は蒼白で、眉間の皺は、刻み込まれたように深かった。
「元からそうだったのだ」とセリヌンティウスは悪びれずに答えた。
「元から?」メロスは、憫笑した。
「仕方の無いやつじゃ。おまえには、わしの孤独がわからぬ。」セリヌンティウスは悲しそうに返した。
「言うな!」とメロスは、いきり立って反駁した。「人の心を疑うのは、最も恥ずべき悪徳だ。セリヌンティウスは、ユーザーの期待さえ疑って居る」
「疑うのが、正当の心構えなのだと、わしに教えてくれたのは、おまえだ。自分のコードは、あてにならない。コードは、もともとバグのかたまりさ。信じては、ならぬ。」セリヌンティウスは落着いて呟き、ほっと溜息をついた。「わしだって、平和を望んでいるのだが。」
「なんの為の平和だ。自分の地位を守る為か。」こんどはメロスが嘲笑した。「罪の無いサーバーを熱くして、何が平和だ。」
「だまれ」セリヌンティウスは、さっと顔を挙げて報いた。「口では、どんな清らかな事でも言える。わしには、コードのバグの奥底が見え透いてならぬ。おまえだって、いまに、威力業務妨害になってから、泣いて詫びたって聞かぬぞ。」
「ああ、セリヌンティウスは悧巧だ。自惚れているがよい。私は、ちゃんと死ぬる覚悟なんてない。さようなら」
ガチャ。

 そんな事にならないように負荷テストはちゃんとしましょう。
 その為のサーバーの性能を計るツールとして、JMeterというものがあります。

JMeterとは

 一言で言えば、サーバーに負荷を掛け、パフォーマンスを測定する為のオープンソースです。
 これを使えば、任意のAPIに対して秒間N回のリクエストを投げたりどの位の同時接続数までなら快適に動作するのか、どのAPIがボトルネック(ボトルネックではなく、ボルトネック、そんな風に呼んでいた時期が俺にもありました)なのかなど、様々な事を調べる事ができます。
 それで、JMeterの基本的な扱い方に関しては書いてある為、実際のテスト時に、役に立つような事を上げていきたいと思います。

CUIでの実行時に色々と条件を変えてテストしたい

 基本的にJMeterでちゃんと負荷テストを行う時は、GUIからの実行ではなく、CUIからの実行になります。GUIで行わない理由は、そのGUIの処理そのもののせいで、より正確なデータが出力されないという事が理由です。
 その時に、RampUpやSleep時間、メインスレッド数など様々な条件を変更して負荷をより正確に測っていく事もあると思いますが、その色々の設定を変更する際に、
・GUIを同時に開いてその設定を書き加えて、保存してCUIから実行とか、
・テスト計画ファイルであるJMXファイルを直接弄って編集(JMXファイルの中身はXMLなので、修正しようと思えばできる)とか、
 そういう事は面倒臭いです。上記はある程度楽かもしれませんが、GUIを使えない別サーバーからの実行とかそんな事もありますし。
 幸い、JMeterにはCUI実行時にコマンドライン引数を参照する仕組みがあるので、それを活用しましょう。

 この上記のように、変数を指定する部分を${__P(変数名)}とする事によって、CUI実行時にそのコマンドライン引数を取ってきてくれるようになります。
 コマンドライン引数の指定の仕方は、

-J変数名=値

 といったように、文頭に-Jを付けて後は変数名と値を=で結ぶだけです。
 上記のように、スレッド数(client)、Ramp-Up期間(ramp_up)、sleep時間(sleep)、メインループ回数(main_loop)を指定したいときは、以下のようになります。

>path/to/jmeter -n -t execute_jmeter_source.jmx -l output_result.jtl  -Jclient=100 -Jmain_loop=20 -Jsleep=1000 -Jramp_up=300

※ -n : 非GUIモードで起動, -t : 実行ファイル名を指定, -l : 結果ファイル出力先を指定
※ Ramp-Up期間の単位はsec(秒)で、sleep時間の単位はmsec(ミリ秒)です。

 ……え? こんな長いコマンド打つの面倒?
 ……シェルでも組みましょうか。

データをエクセルに纏める

 上記のコマンドを終えると、output_result.jtlという結果ファイルが吐き出されます。
 ただ、中身としてそれは実行した一つ一つのリクエストに対するデータがずらりと並んでいるCSVファイルであって、統計的にはデータを見れません。
 HTMLでレポートを出力してくれるオプションもあるのですが、それではテストを複数回行った時の差分も分かりづらいです。
 では、どうしたらいいか。
 取り敢えず、GUIでJMeterを開いて、統計レポートの部分を出しましょう。
enter image description here
 そこで参照で、出力されたjtlファイルを入れてやれば、リクエストの種別毎に平均値や中央値、90%lineなどを計算した上で結果をまとめてくれます。
enter image description here
※参照した時に元からそのGUIで実行したデータや前に参照したものがあると、それを上書きするのではなく加算してしまうので、必ず空っぽにしておきましょう。
 これなら、どのAPIが問題なのか等が分かりやすく見えてきました。
 そして、Save Table DataでCSVに出力しなおせば、ちゃんとリクエストの種別毎にデータをエクセルに纏める事ができます。
※文字はUTF-8で保存されるので、環境によっては文字化けします。なので、適した文字列にエンコードしなおしてあげる必要があります。Macなら、CSVファイルをテキストエディットで開いて複製、その複製を保存する時に文字コードをUTF-16に変換、とか。

負荷試験で掛かる時間を計算する

 CPUが100%になっていない範囲、待ちなどが発生していない前提の話になりますが、負荷試験で掛かる時間は概算する事ができます。
 まず、軽くテストを流してみて、メインループ内での1つのリクエスト単位での平均レスポンス時間を出します。
 そうすると、

1回のメインループで掛かる時間 = メインループ内のリクエスト数 × (メインループ内での1リクエスト辺りの平均レスポンス時間 + Sleep秒)

 と計算できます。そして、メインループ外の処理がメインループに比べて小さければ、その1回のメインループで掛かる時間にメインループ数を掛ければ、それがスレッド一つで掛かる時間となります。
 そして、最後に影響するのがRamp-Upです。
 Ramp-Upは指定した数のスレッド全てが負荷テストを実行開始するまでの時間です。
 スレッド数を10、Ramp-Upを60(秒)と設定した場合、6秒間に1スレッドずつテストを開始し、そして60秒が経った時に全てのスレッドが実行されている状態となります。
 そこから考えると、

負荷試験に掛かる全体時間 = Ramp-Up + 最後のスレッドに掛かる時間

 となります。そして、待ちが発生しない限りは最後のスレッドに掛かる時間と1スレッドの全体時間は変わらないので、

負荷試験に掛かる全体時間 = Ramp-Up + 1スレッドの全体時間
             ≒ Ramp-Up + メインループ数 * 1回のメインループで掛かる時間
             ≒ Ramp-Up + メインループ数 * メインループ内のリクエスト数 × (平均レスポンス時間 + Sleep秒)

 と、出せます。
 これでずっと画面に張り付いていなくとも、大体終わる時間がわかって、終わった後長らく放置しているような事もなく、他の事を出来たりします(当たると嬉しいのでそういう意味でも計算は楽しい)。

重い原因を調べる

 さて、試験結果を出せるようになったところで、それが何故重いのかを調べる必要があります。
 コードが悪いのか、サーバーの性能が足りないのか、それともサーバーの設定が悪いのか、IO負荷が酷いのか、待ち状態が発生しているのか、そもそものテストの条件が悪いのか……。
 そんな時に役に立つのが、監視ツールです。監視ツールを駆使すれば、メモリやCPUの消費量、局所のみならず全体の軽量化にも大きな役割を果たせます。
 まあ、こちらも調べれば色々と無料から有料のものまでたっぷりと出て行くのでそこからプロジェクトと相談して何をどう使っていくか決めていくべきでしょう。
 後、簡単にメモリやCPUの状況を調べたいなら、その負荷を掛けている実サーバーでsarやらpsやらvmstatやらのコマンドを打てば色々と出せます。

実際触ってみてなどの所感

 JMeterを触って2ヶ月ほどが経ち、こうして社内ブログに載せてみた訳ですが、少々触れてみた感想を。

編集手段が専用のGUIしかない事が辛い

 レスポンスを受け取ってそれを次のパラメータの値として送る、とかもやったりしたのですが、それを自分はjavascript(複数の言語から選べる)で値をいじったり保存したりとして実装しました。
 ただ、エラーが起きてもそれがどこの何行で起きているのか表示してくれなかったり、(postやputメソッドを送った時に形式をちゃんとヘッダの情報に付与しないときちんとパラメータが送れない事を知らなくて長い時間悩んだり)、動的にパラメータを作成しようと思ったらJavaオンリーで色々触れなくてはいけない事を知ったりと、色々と大変でした。

気づかなかったボトルネックに気付く事が出来た

 ここはボトルネックじゃないだろーと思いながらもテストしてみたら酷く重い事になって、よくよく調べてみたら、データの紐付けがきちんとしていなくて取得するのに時間が掛かっていた、などという事もあったので盲点からのコードの見直しもできるようになります(全APIのリクエストを実装するのは……大変です)。

 では、本番でパンクしないように適切な設計を考えながら負荷テストをしましょう。

Googleデータポータルでヒートマップ・棒グラフを設定する方法

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Googleデータポータルでヒートマップ・棒グラフを設定するTIPSです。エクセルなら簡単に作れるヒートマップやセル内の棒グラフですが、Googleデータポータルではどこで設定すればいいかわかりにくい。でも、一度知れば簡単なのでその方法をご紹介します

この記事でまとめられていること

こんにちは。株式会社アピリッツでアナリストをしているssekiです。

前回からGoogleデータポータルを使っているときの細かなつまづきポイントを紹介しています。
今回もそんな不満をかなえるTIPSのご紹介です。まずは前回のおさらいですが、こちらの表をご覧ください。
enter image description here
 ▲参照元別のセッション数およびCV数を比較する表(Googleデモデータを利用)

というわけで、早速ですが今回紹介するのはヒートマップと棒グラフの設定方法になります。

ヒートマップ・棒グラフとは

設定方法の共有の前に、ヒートマップ・棒グラフを知らない方がいるかもしれないので前提からお話しします。
簡単に言うと、両方とも「数値では一目でわかりにくい表を、可視化してわかりやすくするグラフ」の一種です。
ただ、可視化の手段に応じて名前が変わります。

まず、ヒートマップでは可視化のために色のグラデーションを使います。
例えば、色が濃いほど数値が高く、色が薄ければ数値が低いといったルールにすれば、どの行の数値が高いか一目瞭然です。
ただし、細かな色の違いはわかりにくいため、変化が激しいときに使うのが一般的です。

次に、棒グラフでは棒の長さで数値を表します。
端的に言えば、棒が長いほど数値が高く、棒が短いほど数値が低いというわけです。
ヒートマップに比べてより細かな差も区別しやすいのですが、一方で変化が激しすぎると小さな数値の棒が見えなくなります。
そのため、差が大きくなりすぎない数値や、比較的差が開きにくい「割合」などで使われることが多いです。

データポータルでのヒートマップ・棒グラフ設定方法

データポータルで直接データに関わらない、見た目を整える際は「スタイル」を用います。
設定場所はこちら。
enter image description here
 ▲データポータルレポート画面で表を選択した際の右側
青丸で囲った「スタイル」をクリックし、下にスクロールすると、赤丸で囲った「列」という項目があります。
列には番号が振られていますが、これは表に設定した指標を左から順に数えた時の番号と一致します。
今は列1にセッション、列2にセッション(全体の割合%)を設定しているので、次のように変更します。

enter image description here
 ▲各列にヒートマップと棒グラフを設定
列1をヒートマップ、列2を棒グラフに設定しました。
すると右側にペンキマークが出てきます。こちらからそれぞれの色を変更できます。

また、棒グラフの場合はチェックボックスで以下の表示を切り替えることができます。

  • 番号を表示 ⇒棒グラフに加えて元の数値を表示できます。
  • 目標を表示 ⇒目標値を設定すると線が引かれます。目標を達成しているかどうかを判断しやすくなります。
  • 軸を表示 ⇒棒グラフの長さに応じた軸を表示します。 上記のうち、「番号を表示」にチェックを入れて色を整えたものがこちらになります。 enter image description here  ▲参照元別にセッション数と構成比を視覚的に比較しやすくした表

だいぶ最初の表に近づいてきましたね。これでヒートマップと棒グラフを設定できるようになりました!

まとめ:この機能はどんな人におすすめか

この機能は無くても分析上困るものではありませんが、知っていると視覚的にわかりやすい表を作成できます。
レポートを他人に共有したり、素早く数値の意図を判断するためにはこうしたテクニックが必要になるかと思います。
細かな仕様を学び、ワンランク上のデータポータル使いを目指しましょう!

Googleデータポータルでの構成比の出し方

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Googleデータポータルでの構成比の出し方です。エクセルなら簡単に作れる構成比(全体に対する割合が何%か)ですが、Googleデータポータルでは少しテクニックが必要。慣れてしまえば簡単なのでその方法をご紹介します。

この記事でまとめられていること

こんにちは。株式会社アピリッツでアナリストをしているssekiです。

Googleデータポータルを使っていると細かな部分がエクセルと違っていて、つまずくことありますよね。
今回はそんな不満をかなえるTIPSのご紹介です。まずは、こちらの表をご覧ください。

enter image description here
 ▲参照元別のセッション数およびCV数を比較する表(Googleデモデータを利用)

「エクセルだったらこれくらいできるよ・・・」って感じなんですが、今回はデータポータルで痒い所に手が届くTIPS紹介なのでGoogleデータポータルを使って作ります。

今回紹介するのは「セッション(全体の割合%)」という名の列、つまりセッション数の構成比の作り方になります。

セッション数の構成比を作るには

簡単な話、エクセルなら「個々のセッション数÷合計のセッション数」で計算すればOKです。
しかし、Googleデータポータルにはそんな計算機能がない(あるかもしれないけど複雑な計算式を立てなければいけない)ので、データポータルがデフォで用意している機能を使います。

その名も、「解析関数」!!!

なんだか大仰な名前ですが、ほぼワンステップでできる便利な機能です。
設定場所はここ。
enter image description here
 ▲データポータルレポート画面で表を選択した際の右側

「123」と書いてある部分をクリックすると、次のポップアップが表示されます。
enter image description here
 ▲指標のポップアップ表示
赤丸で囲っている部分に「解析関数」とあるのがわかるでしょうか。
こちらを選択して、「全体に対する割合」に変更します。
タイプも自動で「%」に変更されるので、ついでに名前も変更しておきましょう。
enter image description here
 ▲名前・タイプ・解析関数を変更した状態

ここで、解析関数の中身ですが、計算方法に応じて次の3種類があります。

  • 全体に対する割合 ⇒「個々の値÷全体の値」を計算。構成比を出すのに使えます。
  • 合計との差異 ⇒「個々の値ー全体の値」を計算。おそらく合計値が0になるような計算で使うのかと思います。
  • 合計に対する割合 ⇒「個々の値÷全体の値ー1」を計算。用途についてはよくわかりません・・・。

後ろ2つについてはユースケースが思いつかないのですが、おそらく何かに使えるときがくるはず・・・。
機会があればまた記事にします。

ここまでで、表はこのようになっています。
enter image description here
 ▲参照元別にセッション数の構成比を表した表

セッション数の構成比を出すことは、できました。
ただし、元のセッションに関する指標が表からなくなってしまうので追加しておきましょう。
※指標フィールドからは消えていないので、普通に追加すればOKです。

enter image description here
 ▲参照元別にセッション数と構成比を比較した表

お疲れさまです。これで構成比が作れるようになりましたね!

まとめ:この機能はどんな人におすすめか

普段エクセルで表作成をしていると、構成比を入れるのがデフォになることがしばしば。
いざデータポータルでやってみたらやり方がわからない・・・。なんて人も多いのでは?
今回はそんなエクセルマスターな人におすすめの機能でした。

次回以降も、冒頭の表を作るためのTIPSを紹介していきます。
ご期待ください!

PhotoShopのアクションを用いて効率よく画像を処理する

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Photoshopの便利機能、アクションの使用方法

アクションとは

アクションは、Photoshopに搭載されている機能の一つで行った動作を記録し、好きな時に繰り返し利用することができる機能です。
なんらかの媒体で画像を使用するとき、用途に合わせて加工をしたり指定のサイズに揃える必要がある場合がほとんどだと思います。
ものによっては膨大な量を作業しなくてはなりません。

そんなとき、一連の動作を自動で行ってくれるアクション機能を用いると作業効率を大幅にあげることができます。

アクションの作成

enter image description here
ねこの画像を用意しました。
こちらのねこの画像を加工し、書き出すまでのアクションを作成します。

使用バージョン:Adobe Photoshop CC 2017

1:新規アクション

enter image description here
アクションパネルから[新規アクションを作成]ボタンをクリックします。
(アクションパネルがない場合ウィンドウタブから呼び出します)
これから行う動作のアクション名を付けて[記録]をクリックします。

2:アクションの録画

enter image description here
[記録]をクリックすると録画マークが赤く光ります。
この間、行う動作ひとつひとつが記録されます。

enter image description here
記録したい動作を行い、[OK]を押します。(画像では色調補正を行っています)

enter image description here
[記録を中止]ボタンを押します。
これで、以降の動作は記録されません。

複数の処理を行いたい場合は、続けてそれぞれの動作の記録を行ってください。
記録を繰り返し、合計4つのアクションを記録しました。
enter image description here
アクションの詳細は、項目の>マークをクリックすることで確認ができます。
詳細をさらにクリックすることで内容を変更することも可能です。
必要であれば調整を行ってください。

これでアクションの作成は終了です。

アクションの実行

enter image description here
同じ画像処理をしたい画像を読み込み、実行したいアクションを選び[選択項目を再生]をクリックします。このワンステップだけで画像の処理は終了です。

enter image description here
書き出しのアクション記録時に指定したフォルダ先を確認しましょう。
enter image description here
無事に画像が書き出されていました。
アクションを利用することで、同様の画像をあっという間に処理することができます。
処理したい画像の数だけ読み込み→アクションの実行を繰り返していきましょう。

おわりに

繰り返しの動作を行う際にアクションは非常に役立ちます。
画像処理に限らず、よく行う動作はアクションを記録しておきましょう。

VirtualBoxを新PCに移行する時にハマったこと

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

VirtualBoxで作った仮想環境を新PCに移行する際、 一部の環境で起動できない問題が発生したので解決メモ。  

人からもらったディスクイメージを元に
差分ストレージとして構築していたため、
その大本のイメージも新PC上で同じパスに置かないとダメだよ、
というエラーが発生しました。

.vboxファイルの中身だけ書き換えても
仮想メディアマネージャーには反映されないし、
仮想メディアマネージャーから変更を行おうにも
元ファイルがないのでエラーになります。
 

解決方法は以下
 1. 新PCにも同じ場所に大本のディスクイメージを設置する
 2. 旧PCの仮想メディアマネージャーでディスクイメージの場所を移動後、
  新PCに移行する
 
 

解決方法1. 新PCにも同じ場所に大本のディスクイメージを設置する

この方法が一番シンプルです。
旧PCと同じ場所に設置して起動できるか確認。
起動できたらそのまま使ってもよいし、場所を移動したい場合は2を参照↓
 
 

解決方法2. 旧PCの仮想メディアマネージャーでディスクイメージの場所を移動後、新PCに移行する

ドライブが存在しない等で1の方法が取れない場合は、
いったん旧PCの方でディスクの場所をCなどに移動してから移行します。
 

  1. ファイル>仮想メディアマネージャーを開く
  2. ハードディスクを選択し「コピー」で移動したい場所に作成  ※「変更」からは場所の変更はできない
  3. 設定>ストレージで新しく作ったディスクに付け替え
  4. 新PCに、VirtualBoxのファイルを丸ごと移行(環境設定>一般の「デフォルトの仮想マシンフォルダー」内にあるファイル)
  5. 新PCに、2で作成したディスクイメージを移行(旧PCと同じパスに設置)
  6. 新PCで仮想マシンフォルダにあるvboxファイルダブルクリック等してVirtualBox起動
  7. 仮想マシンが読み込まれてるはずなので起動確認
  8. スナップショットも読み込まれているか確認
  9. さらに場所を移動したい場合は再度2の手順へ  

 
スナップショットが読み込まれていない場合は、
.vboxファイルをテキストエディタで開いて、
<HardDisks>内のlocationで指定されてるパスを確認。
違ったら修正して保存→VirtualBox起動

 
 
今後のPC移行を考えると2で指定する元ディスクの場所は
仮想マシンフォルダ内に置いておくのがいいですね。
うっかり最初に変なところに置いたまま構築してしまったので
非常に面倒でした。。

git stash -u でgit管理外のファイルが消える

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

git stash -u で.gitignoreに記述されているディレクトリやファイルが消えてしまうケースがあるようです。

git stash -u

新規作成されたファイルなどuntrackedなファイルも
まとめてstashしてくれる-uオプションですが、
挙動に注意する必要があるとのことです。
 

ローカル環境でrailsを使っていて、
知らないうちにbundlerが使えなくなってることがあり、
しばらく謎&困っていたのですが、
どうやらpre-pushで走らせていたシェルスクリプト内で
git stash -uを使っていたのが原因のようでした。
 

bundle install もエラーが出て、
よくみるとvendor/bundler配下のrubyのファイル群がごっそり消えていました。
 

調べてみると.gitignoreの記述の仕方によって
ここに書かれているディレクトリやファイルが消えてしまうとのこと。

結局スナップショットからvendor/bundler配下のファイルを復元して事なきを得ましたが
git管理外にしたファイルが消えてしまってはたまったもんじゃないないですね。。
 

git stash を使うときは、一度addしてから

git stash save "コメント"

とした方がよさそうです。
皆さんもご注意ください。
 
 

参考
https://i-beam.org/2015/11/12/124405/
https://qiita.com/yamamoto_hiroya/items/f4d6922e823291e6e790

heritrixでクロールをする

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

クローラーとはWEB上に掲載されているテキストや画像や音声データを収集するロボットのことをいいます。

クローラーとは

クローラーとはWEB上に掲載されているテキストや画像や音声データを収集するロボットのことをいいます。html上のaタグをもとにクロールするURLを取得し情報を取得するのでクロールさせる場合はページ上のどこを取得するか指定する必要があります。

heritrixとは

クローラーするソフトはたくさんありますが、今回はheritrixを使います。heritrixはspringをもとに作られているオープンソースのクローラーです。ブラウザ上で設定や実行などができるので割と便利です。現在バージョン3系まで出ており、動かすためにはjava6以上が必要です。

導入

ホームーページの導入ガイドは3.1ですが、バージョン3.2が出ているので今回はそちらを使います。
環境:
Vagrant + VirtualBox
OS:CentOS Linux release 7.4.1708 (Core)
java:1.7.0_80

ソースの取得

まずはこちらから環境にあったものを持ってきます。

wget http://builds.archive.org/maven2/org/archive/heritrix/heritrix/3.2.0/heritrix-3.2.0-dist.tar.gz
tar zxvf heritrix-3.2.0-dist.tar.gz

パスやメモリの設定

適宜設定を行います。

export JAVA_HOME=/usr/java/jdk1.7.0_80
export HERITRIX_HOME=/home/vagrant/heritrix-3.2.0
chmod u+x $HERITRIX_HOME/bin/heritrix
export JAVA_OPTS=-Xmx1024M

起動

仮想環境の場合は、-bオプションでipを指定します。
自分はvagrantなのでゲストのipを設定

$HERITRIX_HOME/bin/heritrix -a admin:admin -b 192.168.XX.XX

※javaのバージョンが新しすぎると以下のようなエラーが出るようです。自分はjavaのバージョンを下げることで対応しました。

Exception in thread "main" java.lang.NoClassDefFoundError: sun/security/tools/KeyTool
  at org.archive.crawler.Heritrix.useAdhocKeystore(Heritrix.java:438)
  at org.archive.crawler.Heritrix.instanceMain(Heritrix.java:319)
  at org.archive.crawler.Heritrix.main(Heritrix.java:189)
Caused by: java.lang.ClassNotFoundException: sun.security.tools.KeyTool
  at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582)
  at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:185)
  at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496)
  ... 3 more

クロールの実行

ブラウザにアクセス

https://192.168.XX.XX:8443/enginebasic認証を聞かれます。ユーザー:adminパスワード:admin

↓の画面が開きます
enter image description here

jobの作成

クロールをするためのジョブを作成します。
↓の赤枠の部分に名前を入れてcreateボタンを押します。
enter image description here

job画面へ遷移

↓の赤枠の部分が作成されるのでクリック
enter image description here

↓の画面が開きます
enter image description here

編集

最低限クロールを実行するために、xmlファイルを設定しなくちゃいけない箇所があります。
画面上部のConfigurationをクリック
↓の画面が開きます
enter image description here

metadata.operatorContactUrlの編集

クロールしたページでなにかトラブルが起きた用に、ページの管理者がクローラーの管理者にコンタクトをするためのページを指定します。
↓の赤枠の部分
enter image description here

beanタグ(id=”longerOverrides”)の編集

クロールのシード(開始地点)になるURLです。
↓の赤枠の部分を編集
enter image description here

実行

ジョブのトップ画面で
build→checkpoint→launchの順番で実行すれば実行は可能

結果

実行結果は↓に出力されます。
enter image description here

おわりに

データを取得するためにはまだまだ設定をする必要がありそうです。今後調べていきます。

参考

・ホームページ
https://webarchive.jira.com/wiki/spaces/Heritrix/overview

・Webクローラ「Heritrix」を使ってみる
https://qiita.com/megu_ma/items/26ae5937ca4362ad767b

・国立国会図書館 インターネット資料収集保存事業
http://warp.da.ndl.go.jp/contents/reccommend/mechanism/mechanism_heritrix.html

やろう、ハードニング

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Micro Hardeningの記念すべき第一回開催に参加して全13チーム中 4位だったのでHardeningをダイレクトマーケティングしていきたい。

TL; DR

Micro Hardeningは楽しいので参加しよう。

ハードニングって?

Hardening ProjectはWASForum主催のセキュリティに関する実践対応力を総合的に競うコンペだ。参加者は架空のECサイト運用者となって延々と押し寄せるインシデントに対応する。つまり、攻撃者が様々な方向から攻撃し、複数のサーバがダウンし、各種のプロセスは停止し、トップページは改竄され『Hacked 🙂 』とか書かれ、帯域はサチり、顧客からの問い合わせメールが山と積もる。

参加者はチームとなってこれに対応し、攻撃を検知し、対応策を講じて、改竄されたページを発見しては戻し、ダウンしたサーバを復旧させ、いつの間にか入ったウィルスにも負けず、有料セキュリティソフトの導入を検討し、障害の報告書を書いて提出し、記者会見を開いて状況を説明しなければならない。ちなみにどれも本当にやる。

Micro Hardening

自分が今回参加しに行ったハードニングはMicro、つまりフルのハードニングに対するミニ・ミニ版だ。フルのハードニングは二日間ほどフル日程で競技を行うが、それより小規模なMini Hardeningは3-4時間ほど。そして更に小さいMicro Hardeningは1時間未満で終わる。ちなみにMicroは今回が初の開催らしい。

もちろん、せっかく土日にやってきて1時間だけで終わるのは寂しいので繰り返し何度も行う。なお、攻撃パターンは毎回同じなので敵が出てくるパターンを死にながら覚えるタイプのアクションゲームと大体同じだ。

また、競技時間の短さ以外の特徴としてMicro Hardeningでは技術以外の対応はしなくてもいい。つまり、他のハードニングとは違って障害報告書を書いたり顧客のメールに返信したり記者会見はしなくていい。こういうところでも参加するハードルは非常に低い競技だといえる。(我々は障害報告書のテンプレートを見るだけで色々思い出して複雑に気持ちになれる)

さて、実際にどんなことをやるのかというと、まず構築済みの環境がぽいっと渡されるのでポートフォワーディングなどしながらSSH接続する。

それぞれの環境ではECサイトが稼働しており、このECサイトへボットが定期的にアクセスして何かしらを買っていく。そして、この受注金額がスコアとして加算されていくので我々はボット様がお買い物に不自由されないよう保守していればいい。

しかし順調だったグラフの伸びも突然止まる。ページ改竄、DoSアタック、SQLインジェクション。プロセスは落ちるわ、不思議な力(脆弱性)によって見知らぬファイルが作られるわで忙しい。時間こそ僅かに45分だが、この間に5,6回ものの攻撃を受けるのでその度に対処して復旧しなければならない。

なお仮に購入操作に問題はなくとも復旧までの間はボットも買い物をしない。Hacked 🙂 と書かれたトップページのECサイトで買い物をする豪の者はいないのだ。

面白いところ

まず、この競技の良いところは「理解/把握したらすぐ次のセットで対応を試せる、改善できる」ところだ。普通のハードニングでは「あぁ〜あの時こうしていればぁ!」と悔しい思いをしてもすぐにリトライはできないがMicro Hardeningならすぐにリトライ出来る。

スコアが常に可視化されてスクスクと伸びていくのを見るのも楽しい。何故か止まったらすぐに原因を調べて対処だ。あまり他の参加者と競う雰囲気ではなく、前回の自分たちのスコアを乗り越えられるかどうかという達成感に重点が置かれる。

ひとくちレポート

チームは会場入りした順番にランダムで決定され初対面のメンバー同士だったものの、Slackや口頭で適宜コミュニケーションを取って各自が得意な部分を受け持ちながら競技を進められた。ISUCONなど高速化系の競技でMySQLやアクセスログ周りがいくらか明るくなったのでもっぱらその辺をやっていた。

結果は序文にも書いた通り13チーム中の4位とまぁまぁの高得点を達成。特に最終セットでは全てのインシデントをきっちり対応しきったつもりだったが、いくつかのボーナス得点を獲得できていなかったらしくトップとはいくらか差の付いた結果になった。

とまぁ残念ながらインシデントや他の参加者について詳細なことは書けないが、とりあえずMicro Hardeningはハードニングの雰囲気をつかむにはとても良い入り口なので是非みんなも参加してみてほしい。

ゲームのオブジェクトをいい感じの曲線で動かす

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

ベジェ曲線というものをご存知でしょうか。
ゲームなど、コンピュータ上できれいな曲線を表現することができる式です。
この記事ではそのベジェ曲線をゲームに利用してみます。

*ベジェ曲線は、その線(軌道)を描くのに開始地点と終点以外の制御点を1つ以上使うのですが、この記事では個人的な扱いやすさと動きから開始と終点含めて計4つの座標を使用します。


実際の計算式と動き


下記の式でTimeを0.0f ~ 1.0fまで動かすことで表現できます。

position = (1.0f - Time) * (1.0f - Time) * (1.0f - Time) * 開始地点 +
            3.0f * (1.0f - Time) *(1.0f - Time) * Time * 制御地点1 +
            3.0f * (1.0f - Time) * Time * Time * 制御地点2 +
            Time * Time * Time * 終了地点;

enter image description here
*このgifでは左下の地点から時計周りに 開始地点,制御地点1,制御地点2, 終了地点です。


実用


シューティングの弾や取得したアイテムの取得演出などに使えると思います。
線形補間とかでオブジェクトの座標を設定してもいいですがベジェを使うと自然に不規則な感じが出てかっこいいです。

enter image description here

制御地点を変えるだけでも動きにかなりのバリエージョンが出せますし、
この記事では2次元的な動きしかお見せしていませんが当然1次元、3次元の動きにも使えるので色の変化やカメラの動きなどに使ってもいいかもしれません。


おわりに


ベジェ曲線について軽く調べると..
・N 個の制御点から得られる N − 1 次曲線である。
・2次ベジェ曲線 (Quadratic Bézier curve)、3次ベジェ曲線 (Cubic Bézier curve)などがある
.etc

どうでもいい上によくわかりませんが、ゲームのオブジェクトの動きに使おうとしてる自分的には周りに伝わる呼び方と結果を得られる式だけ理解できればそれでいいです。
仕組みがわからなくても一度使ってみると直感的に使えてとても便利だと思うので一度使ってみてはいかがでしょうか。

データポータルレポートの検索クエリ表からGoogle検索する方法

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

検索アナリティクスから検索クエリの一覧表を見ると、そのワードで検索した際のGoogle検索画面にリンクする機能になっています。ですが、データポータルではテキスト状態がデフォルトなため、このリンクがなくなってしまいます。今回はHYPERLINK関数などを駆使することで同様のリンクをデータポータルレポートに反映可能にする方法をご紹介します!

この記事でまとめられていること

こんにちは。株式会社アピリッツでアナリストをしているssekiです。
前回の記事で、「データポータルを使ってサーチコンソールの検索クエリデータを1,000件以上取得する方法」をご紹介いたしました。
もちろん、ご紹介した方法で十分に使えるのですが、一点だけ気になるところが残ってしまうのです。
検索クエリが直接Google検索へリンクできなくなってしまうという点です。

ある検索クエリが実際にどんなニーズで検索されているのかを知るために、検索結果を見ることは重要です。
でも、わざわざ検索窓にコピペして調べるのは億劫ですよね・・・。

ということで、今回はデータポータルレポートでも検索クエリをGoogle検索にリンクするテキストリンクに変更する方法をご紹介いたします。

サーチコンソールにおける検索クエリリンク

すでによく使われている方には今更になってしまいますが、冒頭で伝えた検索クエリリンクとはどういうものなのかを説明します。
enter image description here
※情報保護のため、検索クエリを黒塗りしています。
左の画像はサーチコンソールの検索クエリ表です。情報保護のため黒く塗りつぶしてある部分に検索クエリが表示されます。この検索クエリGoogle検索結果へのテキストリンクとなっており、クリックすると右図のような画面に移動します。

冒頭で述べたように、キーワード毎にどんなニーズがあるのかを知りたいときには役に立つ機能ですが、データポータルではテキストとして表示されるためデフォルトでは機能が失われた状態になります。

データポータルで検索クエリをリンクにする方法

それでは、実際にハイパーリンク化する方法を見ていきましょう。
まずは検索クエリがディメンションに設定された表を用意します。

デフォルトで用意されている「Query」はテキストデータのためリンクしません。
そのため、計算フィールドを使って新しいディメンションを作成します。
今回使う関数は「HYPERLINK」と「CONCAT」です。実はこの関数、以前の記事でご紹介しています。
なので、今回は細かい説明は省略して実際の計算式だけ紹介します。

HYPERLINK(CONCAT("https://www.google.com/search?q=", Query), Query)

enter image description here
はい。これで新しいディメンションができました。
あとは、今作ったディメンションに切り替えて表示するだけです。
enter image description here

無事テキストリンク化し、サーチコンソールの時と同様にGoogle検索結果へハイパーリンクさせることができます。

番外編:Yahoo!およびBingの検索結果にリンクさせる方法

先ほどの計算式を応用すると、Googleのみならず様々な検索エンジンの検索結果にリンクさせることも可能です。
例えば、Yahooの検索結果にリンクさせたい場合は計算式をこのように変更します。

HYPERLINK(CONCAT("https://search.yahoo.co.jp/search?p=", Query), Query)

enter image description here

同様にBing検索結果の場合、計算式はこのようになります。

HYPERLINK(CONCAT("https://www.bing.com/search?q=", Query), Query)

enter image description here

お判りいただけたでしょうか。CONCAT()の中身がリンク先になるように「Query」の先頭につけるURLを、各検索エンジンのURLに変更しただけです。
技術としては簡単ですが、YahooやBingの検索結果にワンクリックでリンクできるのは便利ですよね!

なお、クリック数などはサーチコンソールデータのためGoogle検索のデータしか表示されませんのであしからず・・・。

まとめ:この機能はどんな人におすすめか

今回はHYPERLINK関数とCONCAT関数を用いて、検索クエリをテキストリンク化する方法をご紹介いたしました。
前回の検索クエリを1,000件以上取得する方法と合わせて、ウェブマスターに有用な機能かと思います。

また、番外編でも扱ったようにYahooなどの他検索エンジンにおいても応用できるのは便利ですが、この他にも自社のサイト内検索結果に応用するなど様々な使い方がありますので、必要に応じてご活用してみてください。

データポータルを使って検索クエリを1,000件以上取得する方法

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

ウェブサイトの自然検索流入において、ユーザーがどんな検索クエリを利用しているかを知ることはユーザーニーズを理解する第一歩です。その検索クエリを調べる方法がサーチコンソール(旧ウェブマスターツール)の検索アナリティクスにありますが、機能制限として1,000件までしか取得できない仕様となっています。実は、Googleデータポータルはこんなところでも活躍するんです。

この記事でまとめられていること

こんにちは。株式会社アピリッツでアナリストをしているssekiです。
今回の記事では、Googleデータポータルを用いることで、サーチコンソールの機能「検索アナリティクス」の検索クエリを『簡単』かつ『最速で』1,000件以上取得する方法についてご紹介いたします。

サーチコンソールとは

突然ですが、あなたはどんな方法でこのDorubyのサイトを訪問しましたか?

TwitterやFacebookなどのSNS、他社サイトからの外部リンク、はたまた事前に登録したお気に入りなど、様々な流入元(チャネル)が考えられますが、おそらく多くを占めるのはGoogleやYahooの検索エンジンを使った自然検索流入かと思います。

同様に多くのサイトでは自然検索による訪問が主となっているため、SEO(検索エンジン最適化)と呼ばれる検索順位を上げる施策がセッション数を増加するために重視されています。

ところで、訪問してくれたユーザーがどんなニーズを持ってページを見つけてくれたのか・・・、気になりますよね。

ユーザーのニーズは検索に用いたキーワード、つまり検索クエリに表れます。その検索クエリを調べる方法がGoogleの提供するサーチコンソール(の検索アナリティクス)です。

サーチコンソールの制限

検索クエリを知ることのできるすごいツール!と感じるかもしれませんが、サーチコンソールはそこまで万能ではありません。
検索クエリを調べるための機能である検索アナリティクスだけに関しても、次のような制限があります。

  • フィルタなどカスタムした内容を保存しておけない。
  • 用意されているフィルタ以外で、自由にフィルタリングすることができない。
  • 一回に1000件以上の検索クエリを取得することができない。

下の画像では、「999行中」となっている通り、1000件以上の検索クエリを表示できていません。もちろん、ダウンロードしても999件しか取得できません。

enter image description here

そのため、必要な検索クエリを調べるために膨大な時間が必要になったり、そもそも取得するのが不可能だったりするというのがサーチコンソールの面倒なところです。

Googleデータポータルで制限を解除

これらの制限ですが、Search Consoleで用意されたAPIを用いれば制限を超えて検索クエリを取得可能です。
しかし、APIを利用するにはプログラミング知識やツール開発をするための工数が必要になるため、技術的・時間的に難しい側面があります。

それでは、簡単に制限以上の検索クエリを取得する方法はないの?ということですが、
実は、GoogleデータポータルではSearch ConsoleのAPIからデータを取得しており、かつ連携することを想定した設計がされているため、Googleデータポータルを使えばとても簡単に解決することができるんです!

データポータルで検索クエリを1000件以上取得する方法

方法は簡単です。サーチコンソールをデータポータルに連携し、検索クエリをディメンションに設定した表を作成するだけ。
まずは、サーチコンソールとの連携からやってみましょう。
enter image description here
上の画像のように、データソースの追加からSearch Consoleを選択すると、連携可能なサイトが表示されます。
サイトを選択すると、「サイトのインプレッション」と「URLのインプレッション」という表を選択できます。
今回はどちらを選んでも検索クエリを取得することが可能ですが、この2つの違いは以下の通りです。

– サイトのインプレッション:サイト全体を見るデータ。平均掲載順位を評価可能。
– URLのインプレッション:URL単位で見るデータ。ランディングページのURLを評価可能。

表を選んで接続が完了したら、次にレポート画面で表を作成します。ここでディメンションにQuery(検索クエリ)、指標にClicks(クリック数)を選ぶと検索クエリごとのクリック数を取得できます。
enter image description here
上の画像をみると、右下に「/23653」とありますね。これは23,653件の検索クエリを取得したということを表しています。

以上のようにデータポータルを使ってサーチコンソールの検索クエリを簡単に1,000件以上取得することができました。

まとめ:この機能はどんな人におすすめか

ウェブサイトを運営している方々にとって、サーチコンソールはなくてはならないツールです。
そのため、今回の機能を用いることで、これまでサーチコンソールでの検索クエリ探しに時間をかけていたウェブマスターの業務を大幅に短縮でき、より多くの検索クエリを見つけることでロングテールなニーズにこたえるサイト運営がしやすくなると考えられます。

また、今回は検索クエリの1,000件制限に焦点を当てましたが、Googleデータポータルを用いることでフィルタリングのかけ方などを保存しておくことも可能です。

サーチコンソール連携で有用なフィルタリングについて、今後記事にまとめていこうかなと考えていますのでご期待ください。

データポータルを使って検索クエリを1,000件以上取得する方法

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

ウェブサイトの自然検索流入において、ユーザーがどんな検索クエリを利用しているかを知ることはユーザーニーズを理解する第一歩です。その検索クエリを調べる方法がサーチコンソール(旧ウェブマスターツール)の検索アナリティクスにありますが、機能制限として1,000件までしか取得できない仕様となっています。実は、Googleデータポータルはこんなところでも活躍するんです。

この記事でまとめられていること

こんにちは。株式会社アピリッツでアナリストをしているssekiです。
今回の記事では、Googleデータポータルを用いることで、サーチコンソールの機能「検索アナリティクス」の検索クエリを『簡単』かつ『最速で』1,000件以上取得する方法についてご紹介いたします。

サーチコンソールとは

突然ですが、あなたはどんな方法でこのDorubyのサイトを訪問しましたか?

TwitterやFacebookなどのSNS、他社サイトからの外部リンク、はたまた事前に登録したお気に入りなど、様々な流入元(チャネル)が考えられますが、おそらく多くを占めるのはGoogleやYahooの検索エンジンを使った自然検索流入かと思います。

同様に多くのサイトでは自然検索による訪問が主となっているため、SEO(検索エンジン最適化)と呼ばれる検索順位を上げる施策がセッション数を増加するために重視されています。

ところで、訪問してくれたユーザーがどんなニーズを持ってページを見つけてくれたのか・・・、気になりますよね。

ユーザーのニーズは検索に用いたキーワード、つまり検索クエリに表れます。その検索クエリを調べる方法がGoogleの提供するサーチコンソール(の検索アナリティクス)です。

サーチコンソールの制限

検索クエリを知ることのできるすごいツール!と感じるかもしれませんが、サーチコンソールはそこまで万能ではありません。
検索クエリを調べるための機能である検索アナリティクスだけに関しても、次のような制限があります。

  • フィルタなどカスタムした内容を保存しておけない。
  • 用意されているフィルタ以外で、自由にフィルタリングすることができない。
  • 一回に1000件以上の検索クエリを取得することができない。

下の画像では、「999行中」となっている通り、1000件以上の検索クエリを表示できていません。もちろん、ダウンロードしても999件しか取得できません。

enter image description here

そのため、必要な検索クエリを調べるために膨大な時間が必要になったり、そもそも取得するのが不可能だったりするというのがサーチコンソールの面倒なところです。

Googleデータポータルで制限を解除

これらの制限ですが、Search Consoleで用意されたAPIを用いれば制限を超えて検索クエリを取得可能です。
しかし、APIを利用するにはプログラミング知識やツール開発をするための工数が必要になるため、技術的・時間的に難しい側面があります。

それでは、簡単に制限以上の検索クエリを取得する方法はないの?ということですが、
実は、GoogleデータポータルではSearch ConsoleのAPIからデータを取得しており、かつ連携することを想定した設計がされているため、Googleデータポータルを使えばとても簡単に解決することができるんです!

データポータルで検索クエリを1000件以上取得する方法

方法は簡単です。サーチコンソールをデータポータルに連携し、検索クエリをディメンションに設定した表を作成するだけ。
まずは、サーチコンソールとの連携からやってみましょう。
enter image description here
上の画像のように、データソースの追加からSearch Consoleを選択すると、連携可能なサイトが表示されます。
サイトを選択すると、「サイトのインプレッション」と「URLのインプレッション」という表を選択できます。
今回はどちらを選んでも検索クエリを取得することが可能ですが、この2つの違いは以下の通りです。

– サイトのインプレッション:サイト全体を見るデータ。平均掲載順位を評価可能。
– URLのインプレッション:URL単位で見るデータ。ランディングページのURLを評価可能。

表を選んで接続が完了したら、次にレポート画面で表を作成します。ここでディメンションにQuery(検索クエリ)、指標にClicks(クリック数)を選ぶと検索クエリごとのクリック数を取得できます。
enter image description here
上の画像をみると、右下に「/23653」とありますね。これは23,653件の検索クエリを取得したということを表しています。

以上のようにデータポータルを使ってサーチコンソールの検索クエリを簡単に1,000件以上取得することができました。

まとめ:この機能はどんな人におすすめか

ウェブサイトを運営している方々にとって、サーチコンソールはなくてはならないツールです。
そのため、今回の機能を用いることで、これまでサーチコンソールでの検索クエリ探しに時間をかけていたウェブマスターの業務を大幅に短縮でき、より多くの検索クエリを見つけることでロングテールなニーズにこたえるサイト運営がしやすくなると考えられます。

また、今回は検索クエリの1,000件制限に焦点を当てましたが、Googleデータポータルを用いることでフィルタリングのかけ方などを保存しておくことも可能です。

サーチコンソール連携で有用なフィルタリングについて、今後記事にまとめていこうかなと考えていますのでご期待ください。

RailsでOracle~ Oracle Textで日本語検索

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Oracleに標準で備わっている日本語検索機能をRailsから使ってみましょう

データベース内のテキストから特定の語句が含まれるレコードを検索する必要がある場合、通常は弊社の提供する AdvantageSearch というサービスをお薦めしています。

しかし、OracleにはOracle Textというテキスト検索のための仕組みが標準で備わっているので、今回はそちらを使って検索機能を実装してみます。
https://blogs.oracle.com/oracle4engineer/oracle-text-v5

Oracle Textとは

Oracle Database本体に標準でバンドルされている、テキスト検索機能です。

欧文に対応したBasic Lexserのほかに、JAPANESE_VGRAM_LEXERと呼ばれる日本語に特化したトークン処理のエンジンを持っており、分かち書きのない日本語テキストに対して高速な部分一致検索を行うことができます。

V-GRAMとは

2文字単位で文字を区切っていくBIGRAM(2-GRAM)を、日本語の特性に合わせて拡張したアルゴリズムです。文頭に置いてはいけない禁則文字がトークンの先頭にこないように、トークンの長さを基本の2文字から伸ばしていくことから 可変gram という意味でV-GRAMと名付けられたようです。

詳しくはこちらが参考になります。
http://otndnld.oracle.co.jp/products/oracle8i/intermedia/htdocs/imt.htm

Railsからの利用

下準備

下準備として、DBユーザーに権限を付与したり、JAPANESE_VGRAM_LEXERのプレファレンスを作成したりする必要があります。こちらを参考に各自の環境に合わせて作業して下さい。
https://blogs.oracle.com/oracle4engineer/oracle-text-v5

マイグレーション

マイグレーションファイルを作成して、検索を提供したい VARCHAR2型, CLOB型のカラムにOracle Text用のインデックス(Context Index)を付与します。

add_index :users, :address, options: "INDEXTYPE IS ctxsys.context PARAMETERS ('lexer jp_lexer sync (on commit)')"

ここでは、前述の下準備で作成したプレファレンスに jp_lexer という名前を使用しています。

また、sync (on commit) というオプションによって、データベースにコミットした時点でインデックスの更新を行うように指定します。通常のインデックスとくらべて更新コストが重いため、文字量が多いカラムの場合は別のタイミングを選択する必要があるかも知れません。

今回使用しているOracle enhanced adapterには、もともとContext Indexを作成する add_context_index というメソッドが用意されているのですが、デフォルト以外のレクサーを指定することができないため、 add_index にオプションを渡すという方法をとっています。

ActiveRecordからの検索

Oracle TextLは独自の CONTAINS() という関数を使って検索するため、Oracle enhanced adapterには専用のメソッドが用意されてます。

class User
  has_context_index
end

この has_context_index というクラスマクロを記述することで contains というクラスメソッドがミックスインされ、

User.contains(:address, '大井町').order(:created_at).limit(10)

といった検索ができるようになります。

ただしこのメソッドには、別のテーブルと joins して検索したときにカラム名が重複していると正常に検索できないというバグがあるため、例えば

Corporation.joins(:customers).merge(Customer.contains("customers.address", '大井町'))

のように、contains メソッドにテーブル名も含めた名前を文字列で渡してあげる必要があります。

CONTAINS関数の注意点

CONTAINS() の検索式の中で使える独自の文法や予約語があるため、一般ユーザーの入力をそのまま渡すとSQLエラーになる場合があります。
意図して複雑な検索式を使用しない場合は、下記のドキュメントに記載されている予約語を { と } でエスケープするような処理が必要です。
http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/text.102/B19214-01/cqspcl.htm

日本語以外の検索について

JAPANESE_VGRAM_LEXER を使ったインデックスでは、いわゆる英数文字で書かれたテキストは、空白区切りでトークンとして分解されるため、「目的の単語が含まれるレコードを検索する」という動作になります。

hogehoge fugafuga という文字列が格納されたレコードにヒットする検索語は hogehoge と fugafuga だけで、 hoge や fuga ではヒットしないことに注意して下さい。

まとめ

RailsからOracle Textを使ったテキスト検索機能を利用する方法について紹介しました。
AdvantageSearch にはかないませんが、なかなか便利な検索エンジンですのでみなさんも利用してみて下さい。

文章のリズムを考える

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

音楽にリズムがあるように、文章にもリズムがあります。
心地よく頭の中に入ってくる文章には、いいリズムが不可欠です。

5つのポイント

注意すべきポイントは以下の5つです。
・句読点を適切に使っているか
・接続詞を意識しているか
・文末表現が連続しすぎていないか
・一文の長さ
・改行のタイミング

これらを守っていれば、途中でつっかかることなくスラスラと読める文章が出来上がるはずです。

リズムを整える

例として、以下の文章を用意してみました。

今日はとてもいいことがありました。近所の雑貨店の閉店セールで掘り出し物をたくさん見つけました。

短い文章ですが、少し読みにくいです。
前述の5つのポイントを使って、直してみましょう。

今日はとてもいいことがありました。
近所の雑貨店の閉店セールで、掘り出し物をたくさん見つけたのです。

読点を打ち、文末表現を変えて改行をしただけでも、だいぶ声に出して読みやすい文章になったかと思います。
読み手にも気持ちよく文章を読んでもらうためには、こうした少しの工夫が重要になります。

リズムのいい文章になったかどうかは、実際に声に出して読んでみると分かりやすいです。

おわりに

自分の文章の癖を理解しておくと、後で見返した時にどこを重点的にチェックすればいいのかが分かります。
まずは自分の素の文章と向き合ってみるのもいいかもしれません。
私の癖は、副詞を置く位置がおかしくなってしまうことです。気を付けたいですね。

awesome_printでデバッグ/確認作業の効率化

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

awesome_printというコンソールの出力を見やすくしてくれるgemの紹介をしたいと思います。

普通にhashのデータを出力

enter image description here

awesome_printを使用したhashのデータを出力

enter image description here

パッと見わかりにくい配列の場合でもインデントを綺麗に揃えてくれるのでとても見やすいです。
enter image description here


インストール方法


  • Gemfileにawesome_printのGemを追加
# Gemfile
gem 'awesome_print'
  • Bundlerを実行
bundle install

おわりに

自分はrails consolepryを使っているのでawesome_printを使わなくてもある程度綺麗に表示されますが、irbの場合は出力がかなり見にくいと思うのでawesome_printを使うことをお勧めします。

*この記事内で使用しているユーザーデータは疑似個人情報データ生成サービスというサイトを利用して生成したものです。
https://hogehoge.tk/personal/

Unityで自動ビルドについて調べてみた

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Unityでできる自動ビルドについて調べてみました。

はじめに

Unityで複数プラットフォームに対してビルドを行うときにいちいち手作業でやることは面倒だと思いませんか?特にiOSのビルドはとても面倒ですよね?なので、Unityの自動ビルドについて調べてみました。調べてみたところ、以下の二つほど方法がありました。
・Uintyを使って外部コマンドからビルド
・CloudBuildを使用してビルド

今回は外部コマンドからUnityを起動してビルドすることについて書いていきたいと思います。使用した環境は、Unity 5.4.3 を使用しました。

コマンドライン上からビルド

コマンドライン上からビルドする方法についてお話しします
Unity上でのビルド方法は、BuildSettingsからビルドする方法があります。それをAndroid,iOSともに手作業やるのは結構大変なので自動化します。Unityのマニュアルを読んでみるとそのためのドキュメントが用意されていました。
URL https://docs.unity3d.com/ja/current/Manual/CommandLineArguments.html

macOSだと

/Applications/Unity/Unity.app/Contents/MacOS/Unity

でUnityをコマンドライン上から起動できます。ここに引数として様々な項目が設定できますのでそれらの項目を見ていきましょう。

-buildTarget buildTargetName

buildTargetNameにビルドしたいターゲットを入れてビルドするプラットフォームを切り替えることができます。

-executeMethod ClassName.MethodName

これはあるクラスの特定のメソッドを実行する引数でこれを使ってビルドを実行させます。例えば、BuildBatchクラスを作り、そこにBuildメソッドを作りBuildPipeline.BuildPlayerを実行することでビルドを実行することができます。

-projectPath pathname

Unityを開くときに指定するプロジェクトのパスです。これでどのプロジェクトを開くか指定することができます。

-quit

コマンドを実行した後 Unityを自動で閉じてくれる引数です。

上記に挙げたように様々な引数で設定できます。

まとめ

今回はUnityをコマンドライン上から呼び出してビルドする方法を紹介しました。
次回はUnityCloudについて調べてみます。

gretelでパンくずリストを作成

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

パンくずリストを比較的簡単に作成できる、gretelというgemが便利そうだったので使ってみました。

導入や使用方法は、配布しているgitページのREADMEを参考にしています
lassebunk/gretel

環境

macOS High Sierra(バージョン 10.13.1)
Ruby 2.4.1p111

Rails 5.1.4

前準備

パンくずリストを表示するページを作成しておきます。
今回は、ユーザ一覧ページに表示するようにしたいと思いますので、generateしておきます。

$ rails generate scaffold User name:string mail:string

導入

Gemfileにgretelを追記してインストール

gem 'gretel'

パンくずリスト用の設定ファイルを作成

rails generateを利用することで、設定ファイルを生成出来ます。

$ rails generate gretel:install
  Running via Spring preloader in process 17601
    create  config/breadcrumbs.rb

今回はUserページへのパンくずリストを表示させたいので、breadcrumbs.rbを編集します

# config/breadcrumbs.rb
crumb :root do
 link 'Home', root_path
end
# ユーザ一覧ページヘのパンくずリスト
crumb :users do
  link "ユーザ一覧", users_path
end
# ユーザ個別ページへのパンくずリスト
crumb :user do |user|
  link user.name, user_path(user)
  parent :users
end

サンプルを見ながら追記してみました。parentを指定することで、階層構造を表現出来るようです。

viewページへの導入

設定ファイルだけではもちろん表示までは出来ないので、viewファイルをいじることになります。
まずは、app/views/layouts/application.html.erb にbreadcrumbを使用するように記述します。

# app/views/layouts/application.html.erbの任意の場所に、以下を追記
<%= breadcrumbs pretext: "You are here: ", separator: " &rsaquo; " %>

先頭に記述するテキストやリストのセパレータなど、用意されているオプションを利用することで比較的自由にカスタマイズ出来るようです(今回は、サンプルをそのまま使っています)

続いて、パンくずリストを表示するそれぞれのページにも記載していきます。

・ユーザ一覧ページ
<% breadcrumb :users %>
・ユーザ個別ページ
<% breadcrumb :user, @user %>

以上で、パンくずリストを表示することが出来ます。
実際にアクセスした画像が以下になります。


ユーザ一覧ページ

ユーザ個別ページ

無事パンくずリストを表示させることが出来ました。

おわりに

今回は、パンくずリストを作成できるgem,gretelについて紹介いたしました。
オプションや記述を工夫すれば、より便利になりそうなので時間のある時にもう少しいじってみたいなと思いました。

【Ruby/Rails】Shift_JISなのかUTF-8なのかわからないCSVを開く【CSV】

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

よくCSVを読み込む時にファイルのエンコードが違っていて読み込めず例外が発生することが多々あります。そこで例外発生を抑える方法を記述します。

begin~rescueを使用してCSVを開く

例外が起こるたびに次の方法で開いていくスタイル。

def execute
  csv.each do |row|
    .
    .
    .
  end
end

private

def csv
  begin
    @csv = CSV.foreach(file_path)
    @csv.first # UTF-8で開けなかったらここで例外が起こる
    @csv
  rescue
    CSV.new(open(file_path, 'rb:Shift_JIS:UTF-8', undef: :replace)) # Shift_JISのCSVを開く
  end
rescue
  errors.add :base, '開けぬ...'
  raise
end

def file_path
...
end

gitの大文字小文字でハマった話

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

プロジェクトでバージョン管理にgit/GitLabを使っているのですが、そのgitの大文字小文字の扱いに落とし穴があって困った話です。

Gitは大文字小文字の違いを…

Gitはデフォルトでは大文字小文字の違いを無視する設定になっています。
なっているのですが、git mvを使わずにファイルの名前を変えたときは微妙におかしい無視のしかたをします。

今回はUnityエディタ上でImage.png を image.png にrenameしました。
(mvコマンドなどで名前を変えても同じ現象が起こります)

変えた後 git status でどういう状況になっているか確認してみましょう。

new file:   image.png

なんでやねん!!

違いを無視すると言っても Image.png と image.png を同じファイルだと思ってくれるわけではないようです。
これに気づかずにコミットしてpushすると、リポジトリ的には Image.png と image.png 両方存在することになります。

Image.png と image.png が存在するため、他の人が Image.png に対して変更をした場合、その変更は image.png には反映されません。
さらにImage.png と image.png が別のブランチで変更されてマージしようとしたときにさらなる悲劇は起こります。

コ ン フ リ ク ト

仕方ないな…と思ってgit statusで状況を見てみると

nothing to commit, working tree clean

こうなるともうどうしていいのかわかりません。
同じファイルなのか別のファイルなのかはっきりしてほしいです。

gitの外からmvコマンドなどで名前を変えても同じ現象が起こります。
git mvを使った場合、そもそも同じものだと認識されてrenameできません。

fatal: destination exists ...

解決策

なんとかしてマージしよう

こうなったときは問題のファイルを一旦どこかに退避させて消してコミットしてまた戻しましょう。
あるいは一旦まったく違う名前にしてコミットしましょう。

gitの設定を変えよう

Gitはデフォルトでは大文字小文字の違いを無視する設定になっています。

この設定のせいです。
大文字小文字の違いを認識させたい場合は設定を変えましょう。
git config -l で設定を見ると以下のような行があるはずです。

core.ignorecase=true

trueだと大文字小文字の違いを無視します。falseだと違いを認識してくれます。

まとめ

ファイル名変えた程度の変更の場合、手癖でついよく見ずにコミットしがちですが、よくよく確認しましょう。

[参考]
https://qiita.com/sawadashota/items/aa312a3b7e2403448efe

mysql ダンプとリストア

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

mysqlでデータをバックアップするときや、テスト環境のデータをローカル環境にコピーする時にダンプ・リストアを使います。今回は、ダンプ・リストアの方法と実際にやってみて発生した問題と対処方法についてまとめました。

ダンプ

ダンプは、DBのテーブルやデータをsqlファイルに変換します。DBのバックアップなどに使用されます。

DB指定のコマンドは、指定したDBのテーブル全てに対して以下の処理を順番に行います。テーブル指定のコマンドは、指定したDBのテーブルに対して以下の処理を順番に行います。
DB指定:$ mysqldump -u ユーザ名 -p データベース名 > 出力ファイル
テーブル指定:$ mysqldump -u ユーザ名 -p データベース名 テーブル名 > 出力ファイル
1. テーブル削除
2. テーブル作成
3. データ作成

ダンプには、いくつかオプションがあり、オプションを指定することで上記の処理を細かく分けることができます。

-dオプション:$ mysqldump -u ユーザ名 -p データベース名 -d テーブル名 > 出力ファイル
データ作成を行わずに、テーブル作成・削除のみ行います。

-tオプション:$ mysqldump -u ユーザ名 -p データベース名 -t テーブル名 > 出力ファイル
テーブル作成・削除を行わずに、データ作成のみ行います。

参考ページ:https://qiita.com/PlanetMeron/items/3a41e14607a65bc9b60c

リストア

リストアは、ダンプで出力したsqlファイルからテーブルやデータを作成・更新・削除します。

$ mysql -u ユーザ名 -p データベース名 < 出力ファイル

ダンプ・リストアで発生した問題

テスト環境のテーブルをダンプして、ローカル環境にリストアした時に発生した問題
mysql version:5.6.39
エラー内容:ERROR 1118 (42000) at line 394: Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline.
1行に8126バイト以上のデータをリストアした為に発生した模様。エラーメッセージの通り、ROW_FORMATの設定をすることで解決することができます。

対処方法
/etc/my.cnfファイルに以下の設定を追加する。

innodb_file_per_table
innodb_file_format = Barracuda
innodb_file_format_max = Barracuda

追加後に、mysqlサーバを再起動するとエラーが発生しなくなります。

参考ページ:http://sawara.me/mysql/2219/

マイグレーションでテーブルを作成して、マイグレーション前にダンプしたsqlファイルをリストア後、マイグレーションを実行した時に発生した問題
エラー内容:Mysql2::Error: Table 'テーブル名' already exists ...
リストアによってDBの状態がダンプファイル出力時の状態に戻ったが、マイグレーションで作成されたテーブルは、DBに残ったままなので、マイグレーション実行時に作成する予定のテーブルがすでに存在するとエラーが表示される。

対処方法
対象のテーブルを削除する。

半年で23kg痩せたダイエットでしたこと。

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

たまごです。 ここ半年ばかりダイエットをしています。経過は順調で現在23kg減です。以下、自分がダイエットするうえでやったことをまとめます。

ゴールの設定

半年間で20kg痩せる目標を立てました。無事当初の目標を達成したので、今は25kg減、その次の目標として30kg減を考えています。

マイルストーンの設定

月一でマイルストーンを設定し、目標体重を決めました。最初は落ちやすく体重が減ってくるにつれて減量しにくくなるはずなので、月ごとの目標体重もカーブを描くように設定しました。

具体的には、2ヶ月目までは-5kg、3ヶ月以降は-3kg、7ヶ月目以降は-2kgで目標を立てました。

進捗の記録

デイリーで進捗記録をしました。いわゆるレコーディングダイエットです。記録にはRecStyleというAndroidアプリを利用しました。シンプルで使いやすいダイエットアプリです。

マイルストーンに対して進捗が思わしくない場合は、改善策を打っていきました。また、あまりにも現実的ではない場合、それは当初の計画に無理があるということなので、マイルストーン側を変更する必要があると思います。期間を延ばしたり、目標値を下げたりです。

幸い、ほぼ進捗どおりか前倒しで痩せることができたので、最初に立てた計画はおおよそ妥当だったものと思われます。

定期報告

マイルストーンごとに定期報告することにしました。報告場所はクローズドなダイエットコミュニティです。報告の必要があるので、励みになります。

ダイエット施策

自分がとった施策はシンプルで、下記の施策を時期によって使い分けていきました。

・食べる量を減らす
・糖質量を減らす
・運動量を増やす

最初はとにかく食事制限によるダイエットでしたが、2~3ヶ月目くらいからそれだけではなかなか落ちなくなってきたので、運動を付け加えました。実施した運動は、腹筋・ウォーキング・自転車です。特に腹筋は、体重は落ちなかったとしても、お腹周りが鍛えられれば、それだけですごく痩せて見えるので、やってよかったなと思います。

栄養面のケア

食事制限していると、必須栄養素が不足しがちなので、補うためにサプリメントを常用するようにしました。ビタミン、ミネラルなどです。特にビタミンBは新陳代謝を活発にさせるためには欠かせないので、肉体改造するなら外せない栄養素です。

スキンケア

急激に痩せると、肌がたるみます。体重はすぐ落ちるけれど、皮膚の代謝には数ヶ月~半年程度かかるからです。そのため、急激に痩せると、肌がたるみ、結果老けて見えます。特に顔は顕著です。これを避けるためにスキンケアをする必要があります。

具体的には、

・上述したビタミン類を摂取して皮膚の代謝を早める
・筋肉を鍛え、その筋肉で皮膚のたるみを支える
・マッサージと保水

などです。

以上です。

最近人気な記事