いっきのblog

技術とか色々

Laravelでメール送信する際にSendGridを使う

f:id:kzkohashi:20180730231315j:plain自社のサービス(Laravel)では、メールを送信する際にはSMTPの仕組みを利用している。
グーグルのメールアドレスなどもっていればLaravelのデフォルトの機能でサクッと作れるのだが、送信する際に毎回認証を挟んでいるので、処理に時間がかかったり、大量に捌くには別の仕組みが必要となってくる。

そんな時、前職でSendGridを利用していたのを思い出したので今回利用してみたという話。

SendGridとは?

メールの配信に特化したSaaS
12000通/月までは無料で使えるので、試したい人はサクッと試せていいね。

sendgrid.kke.co.jp

また、メール配信の仕組み上サードパーティを通すと信憑性にかけてしまうため、SendGridでは SPFDKIM の機能を提供している。
詳細に関しては、以下を参照

簡単にいうと、SPFは送信元のIPアドレスがそのドメインからから許可されていて、DKIMドメインが署名していることと改ざんがされていないことを保証することらしい。

ここら辺の記事も参考になりそう。

milestone-of-se.nesuke.com

SPF/DKIMの設定方法

Whitelabel機能にドメインを設定する

SendGridではWhitelabelという名前でSPFDKIMなどの機能を提供している。
ただし、最低プランの課金は必要なので注意。 f:id:kzkohashi:20180411201441j:plain

DNSでの設定

次に先ほど取得したドメイン名とデータをDNSのレコードに追加する。
(画像はRoute53)

f:id:kzkohashi:20180411201454j:plain

結果

Laravelの設定の前に結果だけいってしまうと、画像の通り設定したドメインから署名されたことになっている。

f:id:kzkohashi:20180411201508j:plain

Laravelでの設定

SendGridでは色々な言語でライブラリを提供している。実際にPHPで実装している例もある。

sendgrid.kke.co.jp

Laravelにはすでにメール機能があるので、それに乗っかりたいなーと思っていたら、ありました。公式の実装とは少し異なっていて、Guzzleで通信周りを実装しているみたい。

github.com

READMEにもあるように、数カ所設定したら実装完了で、ブログで説明することがなかったというくらい簡単に使えた。あまりにも寂しいので、メールを送信してる箇所を一部見せる。

<?php

public function toMail($notifiable)
{
    return (new MailMessage)
                ->subject('登録お申し込み受け付け')
                ->greeting($this->client_name .'')
                ->line('この度は、FIXAへお申し込みいただき誠にありがとうございます。')
                ...
                ->cc(env('OFFER_MAIL_ADDRESS'))
                ->view('mail.regist');
}
    

感想

SendGridではメールの開封有無や送信の失敗とかも取得できるので、近々そこらへんも取得してみたいと思う。

LaravelにSentryを導入してアプリのエラー監視を楽にする

サーバーの監視をするためにMackerelを導入をして1ヶ月くらいたった。時折なるアラートになんだか嬉しさを感じつつ(ダメだけど)、そろそろアプリのエラー監視もしっかりやらないとと思ってSentryを導入した話。

kzkohashi.hatenablog.com

Sentryとは?

オープンソースにもなっているイベント監視ツール。
主にエラー監視に使ってる例をよくみる。

sentry.io

ただ、自前のサーバーの用意や設定などを考えるとSaaSとしても提供しているため、今回はそちらを利用する。

ライブラリの導入

インストールは5.5以上だとすごく簡単。

github.com

app/Exceptions/Handler.phpに関数を追加するのと、.envSentry側で発行されたキーを入力するだけで準備完了。

エラーを起こして使ってみる

Slackにエラーを飛ばすことができるので、設定しておく。

sentry.io

実際にエラーを起こった場合このように、エラー(イベント)単位でIssueとしてみれる。 f:id:kzkohashi:20180407152454j:plain

詳細はこのようになっている。 f:id:kzkohashi:20180407152512j:plain

良い点としては

  • エラーの内容がWeb上で確認できる
  • 過去に起きたエラーかがわかる
  • 過去に対応した場合はその対応内容がわかる

まだローカルでしか試してないため、本番で運用したらここに追記しておく。

その他サービス

Mackerelもログ監視をできるみたいだが、どっちかっていうとミドルウェアとかのログチェックに使いそう。

mackerel.io

Datadogもログ監視の対応してるみたいで、こちらもインフラよりな使い方の紹介が多い。
ログの時間とサーバーのメトリクスの時間が連動するようになったっぽい・・・これは良さげなので別の機会にやってみたい。

www.datadoghq.com

終わりに

アプリのエラー検知はCloud Watch Logsなどで軽くやっていたけど、Sentryを使うと便利すぎて戻れなさそうだなと思った。
今回はサーバーサイド側をやってみたが、フロント(React.js)にも対応してるみたいなので、そちらも近々導入してみる。

React – Sentry Documentation

Think Stats(第2版)を読む:1章

最近、統計処理について詳しくなろうと考えていたところThink Stasをオススメされたので、メモがてら勉強した事を書いていこうと思う。(今回は1章のみ内容)

Think Stats 第2版 ―プログラマのための統計入門 | Allen B. Downey, 黒川 利明, 黒川 洋 |本 | 通販 | Amazon

2015年ごろに第2版が出版されて内容が多少変わっているので買う人は気をつけておこう。

1章: 探索的データ解析

統計処理をして行く上での流れだったり、Pythonなどの使い方がメインの話になっている。
内容としては、「第一子の出産は予定日よりも遅れることが多いか」についての議題。

事例証拠(anecdotal evidence)

雑談で出てくるような、「私たちはこうだから、絶対こうなる」や「友達たちはこうだったからこうである」のような個人的な経験のデータに基づいている、未公表の報告のことを言う。以下の理由から説得力がないため失格とのこと。

  • 小さすぎる標本数
    • 調べる人数が少ないとダメ
  • 選択バイアス
    • あることに関心を持ちすぎて、データの選択方法が結果を歪める
  • 確証バイアス
    • ある説を信じしてる人はその例ばかり提供してしまう(逆も然り)
  • 不正確さ
    • 人は忘れるものだ

統計的なアプローチ

事例証拠がだめならじゃあどうすればいいのか?
そんな時こそ統計を使おう!!ということで以下のようなやり方がある。

  • データ収集
    • ある程度のデータを集める(全米データとか)
  • 記述統計学
    • データの特性を簡潔に示すような統計値を求める
  • 探索的データ解析
    • 問題に対して、有用なデータのパターンや差やその他の特徴を探す
  • 推定
    • 標本から得られたデータを使用して、母集団の特徴を推定
  • 仮説検証
    • 偶然の結果じゃないのかを確認する

調査方法

調査方法には主に2種類ある。

  • 横断的調査
    • ある時点における母集団のデータを調査する方法
  • 縦断的調査
    • ある母集団を長期的に、繰り返して行う調査方法

ある問題に対して、どちらの調査が適切かを見極めるのが大切になる。

メリットデメリットについてはここら辺参考になる。

psycologystudy.blog.fc2.com

DataFrameを扱う

Pythonには、データをRDBcsvのように扱いやすくするためのPandasというライブラリがある。
この章では、データをインポートしたあたりからは黙々とデータフレームの表示とか加工をしていくことになるので、軽く他のサイトとかで勉強してもいいと思う。

参考になったサイト。

dev.classmethod.jp

qiita.com

終わりに

  • 最初の知識以外はほとんどPandasをいじってるだけだった
  • Pandas自体は、色々な機械学習ライブラリであまり対応していないため最近下火?(事例証拠です笑)
  • 色々な用語が出てくるため、この章でしっかり覚えておくと進めやすそう

リモートワークのMTGでペンタブ + RealtimeBoardを使ったら捗った

最近、実験的に週1~2でリモートワーク開発を行なっている。
その中で、どうしてもMTGの質がなかなか上げれずにいたけどかなり改善したので書こうと思う。

そもそもの課題

ビデオチャットでただ話すだけの会議については問題なかったけど、アーキテクチャの話や文字だけじゃ説明が難しい事柄についてはホワイトボードが欲しくなってくる。
なので、要件としてはホワイトボードみたくお互いが図とかかけたり共有できるものがほしかった。

RealtimeBoardを使う

とある記事で紹介されてたのがきっかけだったと思う。
名前の通り、リアルタイムでボードを共有するのがコンセプトのサービス

realtimeboard.com

実際使った内容

f:id:kzkohashi:20180401225802j:plain

コードや画像が貼り付けられたりするので、過去にリアルで行われたMTG内容の画像を貼り付けたりすることができるため、実は質が上がってるんじゃないかと思うくらいだ。
(ペンタブで書くのに慣れてないから色々下手。笑い)

豊富なテンプレート

うちではあんまり使えてないけど、ビジネスのアイディアだしや、デザイナーが情報の整理をするためのテンプレートみたいなのが豊富に用意してある。

f:id:kzkohashi:20180401225846p:plain

選んだペンタブ

RealtimeBoardは非常に使いやすいのだが、ペンタブがないとかなりつらいので選んだペンタブについて紹介する。
(リモートする人には原則、貸し出す)

ワコム製Mサイズモデル

ペンタブと言えばワコム
以前自宅用でSサイズを買った経験からすると、小さいとほんと使いづらいのでMサイズを購入。 ザラザラしているので、ピタッとは止まるけどなんか描きづらいというか、ザラザラ感が嫌いなだけかも。

Amazon | ワコム ペンタブレット One by Wacom ペン入力専用モデル Mサイズ CTL-672/K0-C | ワコム | ペンタブレット 通販

HUION製Mサイズモデル

中国の会社のペンタブ。
知らない会社だったのでレビューを入念にチェックしたところ、悪くなさそうだったので購入。
ワコム製とほぼ同じ値段で、スルスル描ける。自分的にはこっちのほうが描きやすい。
また、ペンタブにたくさんついてるボタンが地味にショートカット使うときに便利。

Amazon | HUIONペンタブ H950P 8192レベル筆圧感知 充電不要ペン、OSU用超薄型ペンタブレット | HUION | ペンタブレット 通販

やって見た感想

  • 1on1のMTGなら今のところリアルのホワイトボード並みに使えそう
  • ブラウザオンリーだけあって、少しもっさりする時がある
  • ペンタブ自体の慣れには時間がかかる
  • 複数人で試した時どうなるかを次はやってみたい

React + GoogleAnayticsでページトラッキングする

React+ GoogleAanayticsでトラッキングをするにはライブラリがあるのでそれを使う。

github.com

スター数も1000超えてるし、React + GAでなら一番人気かと思う。

インストールする際のバージョンに注意

react-gaには2.3.4において、初回のイベント以外は送信できないという致命的なバグが存在してる。
(だいぶ困ってた)

github.com

少なくともうちで使っている2.3.5ではすでに修正されているので、それ以降のバージョンをいれるようにしたほうがいい。

遷移するたびにトラッキングする

一つ一つのページに設置するのはめんどくさいので、ページの状態がかわったら送信するようにする。

まず、トラッキングするための親コンポーネントを作成する。

import React, {Component} from "react";
import {Route, withRouter} from "react-router-dom";
import * as titleUtil from "./util/Title";
import * as GaUtil from "./util/GA";

GaUtil.initialize();

class TrackPageView extends Component {

  componentWillMount() {
    this.track();
  }

  componentDidUpdate() {
    this.track();
  }

  track() {
    const currentPath = this.props.location.pathname;
    
    // タイトルが動的なパスはここでは送信しない
    if (GaUtil.isCustomTrackingPath(currentPath)) {
      return;
    }
    
    // パスに紐づくタイトルを設定する(固定)
    document.title = titleUtil.getTitleByPathName(currentPath);
    GaUtil.sendPageView();
  }

  render() {
    // 子コンポーネントを呼び出す
    return <Route children={this.props.children}/>
  }
}

// withRouterを使うことで、色々な遷移に対応できる
export default withRouter(TrackPageView);

次にRouteにあるコンポーネントたちをTrackPageViewの子要素する。

<BrowserRouter>
  // 囲う
  <TrackPageView>
    <Switch>
      <Route exact path="/" component={Lp}/>
      <Route exact path={ROUTE.Client.Login} component={ClientLogin}/>
      <Auth>
        <Switch>
          <Route exact path={ROUTE.Client.Item.Index} component={Items}/>
          <Route component={NotFound}/>
        </Switch>
      </Auth>
    </Switch>
  </TrackPageView>
</BrowserRouter>

こうすることで、子要素のコンポーネントcomponentWillMountが呼ばれる際に毎回トラッキングすることが可能になる。

タイトルが動的に変わるパスの設定

現状は子コンポーネントでデータを取得した際に、以下のように呼んでいる。

document.title = v.name + 'の詳細';
GaUtil.sendPageView();

ここら辺何かクールなやり方があれば知りたい・・。

LaravelでJSON Web Tokenを使った認証方法

Laravel + Reactでサービスを構築した場合に、APIによる認証方法としてJSON Web Token(JWT)を使った例を紹介しようと思う。

JSON Web Tokenとは?

ネットわかりやすく書いてあったので引用させていただくと

JWT(ジョット)とは JSON Web Token の略で、電子署名付きの URL-safe(URLとして利用出来る文字だけ構成される)な JSONのことです。 電子署名により、JSON の改ざんをチェックできるようになっています。 ざっくり言うと、改ざんできない JSON ということになります。 引用:https://qiita.com/gctoyo/items/8d0ffb265845ab8cc87c#jwt-%E3%81%A8%E3%81%AF

というセキュアで便利なものである。

認証として利用する

認証として利用するためには、とても便利なライブラリがあるのでそちらを使う。

github.com

インストールに関しては、公式の方を参考にする。

Laravel Installation - jwt-auth

モデルの設定

設定自体もとても楽で、Laravelにすでにある認証方法の一部変更するだけでいい。
実際の設定しているconfig/auth.phpはこのようになる。

<?php

return [


    'defaults' => [
        'guard' => 'api',
    ],


    'guards' => [
        'api' => [
            'driver' => 'jwt', # ここをjwtにする
            'provider' => 'client',
        ],

    ],


    'providers' => [
        'client' => [
            'driver' => 'eloquent',
            'model' => App\Models\ClientAccount::class,
        ],
    ],

];

ログイン

ログイン時にはいくつかバリデーションを行い、レスポンスにはトークンを返している。

<?php
public function login(Request $request){
    config(['jwt.user' => Client::class]);

    $account = $this->clientAccount->getLoginUserByEmail($request->email);

    // Emailまたはstatusがマッチしない場合
    if(!$account){
        throw new AuthenticationException;
    }

    // passwordがマッチしない場合
    if (!Hash::check($request->password, $account->password))
    {
        throw new AuthenticationException;
    }
    
    // ログイン情報を保存するにチェックを入れた場合
    if($request->remember){
        if (! $token = Auth::guard('api')->setTTL(config('jwt.ttl_r'))->login($account)) {
            throw new AuthenticationException;
        }
    }else{
        if (! $token = Auth::guard('api')->login($account)) {
            throw new AuthenticationException;
        }
    }

    return compact('token');
}

ユーザー側からの利用

トークンの利用については、API利用時にAuthorizationヘッダーにBearer: {取得したtoken}を付与すればできる。以下の記事が参考になる。

qiita.com

感想

  • JWTを使った認証もライブラリのおかげで楽に実装
  • ただ、JWTに関しては色々言われてるので利用する場合はちゃんと勉強しとかないとなとおもった

Mackerel サーバ監視[実践]入門を読んで、監視の第一歩目を始めた話

はじめに

うちのサービスは1月の後半に正式リリースをして約2ヶ月。
スピード重視という言い訳をしつつ、監視をあまりやってこなかったのでここらへんでMackerelを使って監視していきたいと思う。

Mackerel サーバ監視[実践]入門

↓ 監視ちゃんと取り込むきっかけになった自分のブログ

kzkohashi.hatenablog.com

Mackerelはサーバーの監視をするためのSaaSである。
特に何が良いって、はてなのインフラのノウハウがベースなのと、日本語ってのがいい。

mackerel.io

似ているサービスとしては海外のDatadog

www.datadoghq.com

同じく海外のNew Relicがある。

newrelic.com

そもそも監視の勉強が先?

自分は監視に関してはやんわりしか理解してないため、まずは入門本を読もうと思っていた。ただ、まずは監視の設定を先にやらないと今このとき何か起こったとき間に合わないため今回はMackerelの方を先に読んだ感じだ。
こちらは読む予定の本。

ソフトウェアエンジニアのための ITインフラ監視[実践]入門

目次

  • 1章 Mackerelとは何か
  • 2章 Mackerelをはじめる
  • 3章 監視する
  • 4章 アラートを通知する
  • 5章 プラグインを作る
  • 6章 各種ツール連携と運用の効率化
  • 7章 クラウド環境におけるMackerel
  • 8章 発展的な機能
  • 9章 付録

学んだこと

Mackerelの設定本として買ったつもりが、監視をする意義や監視すべき設定など細かく書いてあってすごくためになった!監視の初学 + Mackerelの設定が同時にできるいうお得な気分だ。

第2章: Mackerelをはじめる

はじめてみた

導入して最初に目がついたのが、CPU200%。。。。(笑えないやつ) f:id:kzkohashi:20180319165517p:plain

でも、バッチ自体が止まったことないしなーとおもって細かくみてみると f:id:kzkohashi:20180319165539p:plain

stealに200%もとられている。 t2インスタンス特有?のCPUクレジットの枯渇が問題っぽいのかー。
確かに最近バッチサーバーはずっと動いてたから、こちらは他のインスタンスに変更しよう。

blog.a4works.co.jp

キャパシティプランニングへの応用

こういう言葉があること自体初めて知った。

システムに求められるキャパシティ要件として、ビジネスレベル(データ処理需要、同時利用ユーザー数、同時セッション数など)、サービスレベル(トランザクション量、ネットワークトラフィック量、応答時間など)、リソースレベル(CPU利用率、ディスク利用率、ネットワーク利用率など)を検討し見積もりをする。この際、現状の最大負荷だけでなく、将来予測される最大負荷時にもサービスの水準を維持できるような設計を検討する必要がある。
引用: https://it-words.jp/w/E382ADE383A3E38391E382B7E38386E382A3E38397E383A9E383B3E3838BE383B3E382B0.html

まずはリソースを可視化したら、自分たちのCPUなどがどれくらい使われているのか?ピーク時には足りているのか?余らせてないか?などみてみる。
ちなみに自分たちのAPIサーバーは
f:id:kzkohashi:20180319165626p:plain

やばい。使わなすぎている。無理して良いの使いすぎた・・・下げよう。

サービスメトリックス

PVなどもサービスの状態を可視化して経営層とみよう!ってことが書かれていたけど、今時別のツール使ってみてないかな?というツッコミ。

第3章: サーバ監視

何を監視

  • 外形監視
  • 死活監視
  • リソース監視
  • その他監視

ミドルウェアの監視

mysqlなどの場合別途プラグインをいれる。
行ロックなどの数も取れたりするみたい。

RDSの場合はこちらから。(後の章で説明ある)

mackerel.io

監視ルールの考え方

「実際に対応するものだけに限定すべき」

設定する前は適当にCloudWatchで色々設定してしまってたの反省。

オススメの監視設定フロー

① 全てのサーバに対してのCPU使用率、メモリ使用率、スワップ使用率、ファイルシステムの使用率の監視ルールを設定する
② 各種エラー系のメトリックの監視ルールを設定しておく
③ いったん様子見を見て、特定のロールだけ頻繁にアラートが来るようなら除外条件で無視するか、別途当該ロール用の監視ルールを作成する
④ 障害が発生したときに、特徴的な値の変化をしたメトリックについて監視ルールを作成する。同じ障害を早めに検知できるように、回帰的に監視ルールを育てる。

監視ルールを育てるって良い。 ②までやったけど、③と④はサービスごとによしなに設定だからこれからうちのも育ててこう。

Webシステムにおけるロール編成

構成については以下を参照とのこと。

blog.yuuk.io

Linuxでより多くのパラメーターを取得するには、mackerel-plugin-linuxでとれる。 Mackerelプラグインは豊富で誰でも作れるのでよさそう。

github.com

システムメトリックスの見方

コラムなのに6ページくらい使って監視項目の見方とか書いてくれてる。 少しだけ抜擢すると

ロードアベレージ
「ロードアベレージがある値以上になったら即座に問題である」はあまり意味がない。
それ以上に、どんどん右肩上がりのグラフになっているかの方が問題。マルチコアの考慮もして「loadavg/コア数」を指標とする方が良いみたい。
mackerel-pluglin-multicoreとかでうまく対応できる。

ここら辺のコラムが一番参考になったかもしれない・・・。

CPUのほうはメモ

cpu.user: カーネル以外が使用した時間の割合
cpu.iowait: I/O街により、アイドル状態であった時間の割合
cup.system: カーネルが使用した時間の割合
cpu.idle: I/O街がなく、かつCPUがアイドル状態であった時間の割合

6章: 各種ツール連携と運用の効率化

tmux-cssh x MackerelAPIで同時に多数のサーバーに入る技。

blog.yuuk.io

以前それを改造してawsのログイン機能作ったのでついでに(便利だよ)。

kzkohashi.hatenablog.com

7章: クラウド環境におけるMackerel

AWSインテグレーションを使って、勝手に連携できる。
RDSとかも含めて複数台でパラメーターとってる場合はどうするんだろうっておもってたけど、同じホストとしてパラメーター取得でもできるようで便利。

8章: 発展的な機能

CLIを通じて、グラフなどもすべてJSONで記述が可能とのこと。
Infrastructure as Codeができるし、Ansibleなどと合わせてインフラ周りを全てコードで管理できそう。
以前の会社でもdatadogのグラフ情報をコードにしてる方もいたなぁ。

まとめ

Mackerelを設定するために読み始めた本だが、監視のいろはなども書いてあって凄く勉強になった。とりあえず監視を始めてみよう!って方にはオススメ。
まだまだデータ取り始めたばかりなのでこれからどんどん育てていった結果もかきたい。