読者です 読者をやめる 読者になる 読者になる

sekaie engineers' blog

セカイエ株式会社が主催するエンジニア勉強会について

セカイエの立ち上げから関わってわかった10のこと

スタートアップ

私、増井は、セカイエ株式会社を卒業します!

2012年12月14日 セカイエ株式会社が設立してから早4年が経ちました。

サービス自体は4年半くらいですかね。

思い返すと4年半。いろいろありました。

  • 分社化してリフォーム事業の独立。

  • 2回の事務所引っ越し。

  • GREEの完全子会社化。

なかなか濃い4年半でした。

立ち上げ当初からエンジニアとして過ごして、いろいろ自分なりに気づいたことがあるので書きたいと思います。

1.デスクトップPC < ノートPC

引っ越しが大変。

2回目は引っ越し業者に頼んだからまだましだったけど、

1回目は自分たちだけでやったので、デスクトップを運ぶのはただただつらい。

社内の配線とかめちゃくちゃになる。

基本的には綺麗好き(A型)なんですけど、引っ越し作業もその日の営業終了後からで、

深夜だし、

しんどいし、

眠たいし、

で、

"えいっ"

ってやっちゃいます。

あとで綺麗にするし。→ 絶対やらない。

ルンバと喧嘩します。

LANの銅線むき出しになります。

2.大事なサーバーはちゃんと運ぶ

2回目の引っ越しの時、台車から大事なサーバーがこぼれ落ちるという事件。

案の定ぶっこわれました。

ミラーリングされてたから、なんとか無事だったけど、ただでさえ忙しい引っ越しの日に、まじかんべんです。

3.社内のレイアウトは最初からきちんと決めておく。

人数いなくても、最初から机といすはきっちり敷き詰めておく。

最初は人数すくないのでゆったりスペースとってましたが、

どんどん人が増えていくなかで何度もシマ増やしたりしました。

OAフロア剥がして配線するのは危険です。

電源系統とか、シマハブを連結するとか、そのうち事故りますね。

(サーバーと自販機を同じ電気系統につないでて落ちた経験あり)    

引っ越しの話ばっかり

ついでに

入居するビルを選ぶ時も注意が必要。

ビルによっては、入れたい回線をEPSに設置させてくれないところもあります。

要チェック。

4.求人は大変

エンジニアの採用もやってましたが、GREE子会社化の前と後では、求人希望者に変化を感じました。

名もなきスタートアップは、求人かけるより、知り合いベースで探すほうが良いかと思いました。

いまはセカイエでもWantedlyに掲載してますので、もしセカイエに興味がある方はぜひお話しだけでも来てください。

僕はいませんが。

www.wantedly.com

5.細かい数字は見ない

あくまで僕個人の意見ですが、

事業の前半では、細かい数字は見ないって決めた方がよいと思います。

(決めないとついつい見てしまうので)

このページの直帰率が、、、とか、

このボタンのクリック率が、、、とか

そういった細かいPDCAを回す時期とそうじゃない時期があるので

そういった大きな指針をしっかり決めることも大事だと思います。

ちなみに今のセカイエには分析基盤があります。

sekaie.hatenablog.com

6.仕事ばっかりしない

スタートアップなんで、ゴリゴリ仕事しまくらないといけないとは思いますが、ちゃんとメンバーと遊ぶ時間とか飲みに行く時間とかがすごい大事だと感じました。

あれしよう!とかこうやったらよさそう!とかは、結局思い返すと、ミーティングとか仕事中とかじゃなくて、それ以外の時間に出ることばかりだったような気がします。

f:id:sekaie:20161118155244p:plain

※写真は淡路島ハッカソンの時のチーム:ランチーズの一枚。

7.品質とスピードの間で

  • 昔:設計の質とか、コードの質とか、そんなもんは後回しじゃー。 

  • 今:なんでこんな設計なってるんや!なんじゃこのコードは!

設計の質とか、コードの質とか、当時はあまり考えてなかった。

それより、スピードとか量を重視してました。

(サービス終了したら元も子もないしなって気持ち。あとは、そこまで知識や経験もなかったってのも事実。)

今はその負の遺産にエンジニアメンバーは悩まされてることが多いかと思います。

例えば、データベース。

いろんな仕様変更によりどんどんカラムが追加され、

いま一番カラム数おおいテーブルで92カラム。

すごいな。。。 

たぶん半分くらいは使ってないんじゃないかな。。。

こうゆう状態を作り上げてきた過去の自分を呪います。

サービスのステージによって左右される部分は多大にありますが、それを分かったうえでやってるのか、なんとなくそうなってるのか、では全然違います。

8.属人化について

一般的には属人化ってよくないのですが、どうしようもないです。(メンバー少ないし)

でもメンバーが増えてきたらチャンスと思って、どんどんアウトプットしていくべきだったなと思います。

僕自身なんでも自分だけで完結させようとしてしまうタイプなので、もっと回りのメンバーと一緒に進めるってことがすごく大事だと感じました。

あと、非エンジニアをエンジニアにするってことも大事かなと思います。

何でもかんでもエンジニアにお願いする。と属人化ならぬ属エンジニア化しちゃうので、それもよくないなって。

資料つくったり、仕組み作ったりはエンジニアの仕事。というかわかる人が資料作ってみんなに展開すればいいし、そこにプログラムが必要ならエンジニアが作ればいいと思う。

9.勉強会には参加するべし

セカイエでは毎週水曜日、おもに開発部のメンバーのおもにエンジニアメンバーで社内勉強会をしています。

これが意外というかなんというか、すごくいい方向に働いています。

勉強会でやった主なこと

  • 勉強 (メンバーそれぞれがいま気になる技術とかを調べて、資料つくって発表)

  • LT

  • ハッカソン

  • アドベントカレンダー 2015

  • 輪読

  • sekaie tech talk (セカイエ主催のオープンな勉強会)

などなど

この勉強会をきっかけに、社外勉強会に参加する人も増えたり、お知り合いの方伝いで合同勉強会を開催したりと、活動の幅が広がっています。

そして、このエンジニアブログも社内勉強会の中で書こう!となり始まっています。

ちなみに今年もアドベントカレンダーやります。

qiita.com

10.ベンチャー企業っていいな

もともとは1ポンコツエンジニア(ここらへん知ってる人はもうほとんどいないですが)として入社した僕が、ここまで成長できたのは

ベンチャー企業だからなのかなって思いました。

いろんな部署のみなさまと関わらせていただいて、

なんでもかんでもやらされる。とりあえずやるしかない。って状態。

結構好きです。

そんな環境が、エンジニアとして、社会人として、人として、成長できた一番の理由だと思ってます。

他の会社なら、ここまでいろいろ任せてもらえることも無いだろうし、ほんとにセカイエで仕事できてよかったなーーーーって思ってます。

以上、エンジニアらしいことはそんなに書いてないけども、ぼくがセカイエの立ち上げから関わってわかった10のこと

です。

ほとんど誰の参考にもならないような情報ばっかりな気がしますね w

ほな。

集計テスト時の BigQuery のテストデータについて

はじめに

おはようございます。こんにちは。こんばんわ。佐々木です。

さっそくですが、皆さんテストしてますか?

自分もそんな得意ではないですが(むしろ苦手ですが)、サービスの規模も大きくなってきたので最近必死にテストを書いています。

サービス自体は Rails で書かれているので rspec を使ってコントローラやモデルなどのテストは例に倣ってそれっぽくテストが出来ています。

が、集計のテストがなかなか難しいです。

多分一番大変なのはテスト用のデータを用意したりするところだと思います。

特にログデータや MySQL snapshot のデータは BigQuery に入れていてそのデータを集計していて、BigQueryのデータを用意して rspec であれこれするのはなかなか大変です。

この辺をどういう感じでやるか迷っていましたが、なんとなくうまくいきそうなので今回はこの辺を紹介したいと思います。

集計のテストにおける今回の目標と今回のテスト対象

集計に関するテストが0だったので、今回は指定のデータから意図したデータを集計できているか。というところをゴールにしたいと思います。

多分他にも考えなくてはいけないところはあると思いますけど最初の一歩のゴールとしてはまあ良しとしましょう。

今回のテスト対象ですが、MySQL の snapshot データを集計しやすくする中間テーブルデータを生成するところを対象とします。

ので、複数のテーブルデータと中間テーブルのデータの整合性が保たれているかをチェック出来るようなテストを書いてみたいと思います。

テストデータのローダー

では、準備としてテストデータをローディングする所です。

rspec では FactoryGirl があるのでデータを簡単に用意することが出来ますが、 BigQuery には無いので自前で用意しました。

最初は BigQuery の load を使おうと思ったんですが、遅いです。結構遅いです。

なので schema, rows をもとに SQL を生成してその結果を指定のテーブルに挿入しています。

module FactoryBigquery

  def self.load(job)
    @_bigquery = GCP::BigQuery.new
    self.create_table(job[:dataset], job[:table], job[:schema], job[:rows])
  end

  def self.parallel_load(jobs)
    @_bigquery = GCP::BigQuery.new
    Parallel.map(jobs) do |job|
      self.create_table(job[:dataset], job[:table], job[:schema], job[:rows])
    end
  end

  def self.drop_table(dataset, table)
    @_bigquery = GCP::BigQuery.new
    res = @_bigquery.drop_table(dataset, table)
  end

  def self.create_table(dataset, table, schema, rows)
    @_bigquery.create_dataset(dataset)
    from_expr = rows.map{|row|
      select_expr = row.map{|k, v|
        s = schema.select{|s| s[:name] == k}.first
        if s[:type] == 'INTEGER'
          "#{s[:type]}(#{v}) AS #{s[:name]}"
        else
          "#{s[:type]}('#{v}') AS #{s[:name]}"
        end
      }.join(', ')
      "( SELECT #{select_expr} )"
    }.join(', ')

    sql = "SELECT #{schema.map{|s| s[:name] }.join(', ')} FROM #{from_expr}"
    res = @_bigquery.copy_table_by_query(sql, dataset, table, { 'query.writeDisposition': 'WRITE_TRUNCATE' })
    @_bigquery.wait_job(res[:job_id])
  end
end

テスト

上記のデータローダを使って実際にテストを行います

require 'rails_helper'
require 'importer/molding/user'

describe ::Importer::Molding::User do
  before :all do
    FactoryBigquery.parallel_load([
      {
        dataset: :snapshot,
        table: 'prefs_20160101',
        schema: [
          { name: 'id',               type: 'INTEGER' },
          { name: 'name',             type: 'STRING' },
        ],
        rows: [
          { 'id' => 1, 'name' => 'TEST_PREF' },
        ]
      }, {
        dataset: :snapshot,
        table: 'cities_20160101',
        schema: [
          { name: 'id',               type: 'INTEGER' },
          { name: 'name',             type: 'STRING' },
        ],
        rows: [
          { 'id' => 1, 'name' => 'TEST_CITY' },
        ]
      }, {
        dataset: :snapshot,
        table: 'users_20160101',
        schema: [
          { name: 'id',           type: 'INTEGER' },
          { name: 'family_name',  type: 'STRING' },
          { name: 'last_name',    type: 'STRING' },
          { name: 'pref_id',      type: 'INTEGER' },
          { name: 'city_id',      type: 'INTEGER' },
        ],
        rows: [
          {
            'id' => 1,
            'family_name' => 'TEST',
            'last_name' => 'NAME',
            'pref_id' => 1,
            'city_id' => 1,
          }
        ]
    ])
  end
    
  describe '#import' do
    before(:all) do
      FactoryBigquery.drop_table('moldings', 'users_20160101')
      importer = ::Importer::Molding::User.new
      importer.date = '20160101'
      importer.import
      bigquery = ::GCP::BigQuery.new
      res = bigquery.query("SELECT * FROM moldings.users_20160101 WHERE id = 1")
      @rows = bigquery.result_to_hash(res)
    end

    it do
      row = @rows.first
      expect(row['id'].to_i).to eq 1
      expect(row['name']).to eq 'TEST NAME'
      expect(row['pref_name']).to eq 'TEST_PREF'
      expect(row['city_name']).to eq 'TEST_CITY'
    end
  end

それでは実行してみましょう。

$ bundle exec rspec spec/importers/importer/molding/user_spec.rb
.
Finished in 42.02 seconds (files took 2.68 seconds to load)
1 examples, 0 failures

無事テストが通りました。

おわりに

今回はテスト化をする上で集計時のテストのデータを用意する方法と集計時のテストを行う方法について紹介しました。

まだ試行錯誤をしている段階です。

もっと良いテストの方法があればぜひ紹介していただければと思います。

ほな!

GCP の Natural Language API が公開されましたね

おはようございます。こんにちは。こんばんわ。佐々木です

今日 GCP の Natural Language API が公開されましたね。

早速使ってみたデモを載せておこうと思います

APIを有効にする

GCP の Console で Natural Language API を有効にしましょう

API キーを取得する

同じく GCP の Console で API キーを取得しましょう

demo script

さくっとこんな感じで API に POST するだけのスクリプトです。

require 'json'
require 'optparse'
require 'faraday'

require 'optparse'
opts = ARGV.getopts('', 'input:')
input = opts['input']

conn = Faraday::Connection.new(:url => 'https://language.googleapis.com') do |builder|
  builder.use Faraday::Request::UrlEncoded
  builder.use Faraday::Adapter::NetHttp
end


res = conn.post do |req|
  req.url '/v1beta1/documents:analyzeEntities?key=API_KEY'
  req.headers['Accept'] = 'application/json'
  req.headers['Content-Type'] = 'application/json'
  req.body = {
      document: {
        type: 'PLAIN_TEXT',
        language: 'ja',
        content: input
      }
  }.to_json
end

body = JSON.parse(res.body)
puts body['entities'].map{|m| "#{m["name"]}: #{m["type"]}"}.join("\n")

試す

こんな感じで input してあげれば返事が返ってきます。

まだ、ちょっと認識出来る単語が少ない気もしますけどとりあえずOKでしょう

$ bundle exec ruby nl.rb -i '田中さんはゴルフが下手くそです。'
田中: PERSON

終わりに

Speech API も出て Natural Language API と連携して音声解析とかも出来そうですね

GCPバンザイ!!!

ほな

UXデザインを意識しよう PART1

どうも!デザイナーの寺田です。最近初めてハッカソンに参加してとても楽しい思い出となりました。 最近UXデザインに関して少しずつ知識を深めていこうとしておりますので、ブログにまとめていきます。


f:id:sekaie:20160719101959j:plain

UXデザインとは

私たちはやりたいことを達成する為に製品やサービスを利用します。 そこで今までやれなかったことができたり、今までやっていたことがさらに便利になってテンションあがったり、 そういった嬉しい体験をするとさらに利用したいという気持ちになったりしますよね。

簡単にいうとそのうれしい体験のことがUX(利用のユーザー体験)であり、 それをいかに実現していくかを追求することがUXデザインです。

具体的にいうと、UXを目標にして、作り手とユーザーが共に嬉しくなる企画、設計、開発、デザインの過程のことです。

現在ますますこのUXデザインがインターネット業界で重要視されてきています。 理由としてはやはりインターネットの普及や、情報端末の高度化、多様化ですね。

引き金はiPhone

2007年1月にAppleiPhoneを発表してから現在まで、 凄まじいスピードで全世界に普及して、なくてはならないものになりました。

それと並行してスマートフォンは様々な形で進化を続け、 ユーザーそれぞれの利用目的に応じたアプリ等の機能を簡単に即入手することが可能となり、 インターネットを経由して世界中の優れたサービスを誰でも体験できるのが当たり前になってきています。

いわばiPhoneは優れたUXデザインの代表みたいなものですね。 これが世界中に普及していることで、より一層UXデザインのニーズも深まっているわけです。

ユーザビリティーを超えろ

私は業界で働き出してから今までユーザビリティという言葉は嫌という程耳にしてきました。 ユーザビリティーとはユーザーが目的を達成するまでのユーザーの目的を達成するまでのわかりやすさ、操作性の良し悪し等を重視して評価する考え方です。 私も業務をする中でそういった事に対して常に意識をかたむけてきました。

しかし、実際のユーザーの利用環境は物凄く多様化してきていて、比較的短期の視点で考えられているユーザビリティ評価では 製品とユーザーとの関係性を完全に捉えられないという気づきや新たな動きがが2000年代の前半頃から始まっていたようです。

その影響により、「プレジャラブルデザイン」(楽しみのためのデザイン)、「エモーショナルデザイン」(感情的なデザイン) といったキーワードが出現し、ユーザビリティ(操作性)だけにとらわれずに、 感性的側面にも視点を置き、製品やサービスをデザインしていく事が重要であるという流れが発生してきています。

当時は「Beyond usability」(ユーザビリティを超えろ)というスローガンもあったそうです。

そこから本格的にUXの研究がスタートしたと言われています。

うれしい体験

最近でこそ、スマホWebサービスが非常に注目されてきていてUXデザインはそれに属する内容だと思われがちですが、 実際はそういったソフトウェアに限ったことではありません。

UXデザインはどんな分野であっても共通して重要視されるべきものです。そして、いつの時代でも変わらない基準であるものだと思います。

技術というものは、ユーザーから見れば嬉しい体験を得るための必要な手段でしかないということです。 ユーザーからすると、別に技術や機能が欲しいわけではなく、技術の延長線上にある体験に関心があります。

UXデザインはそいういった体験をいかに生み出すかにフォーカスしたものです。

IoT(Internet of Things)

情報通信技術の進化は現在も留まる事を知りません。 みなさんも実感のあるものだとは思いますが、現在ありとあらゆるモノとインターネットとを組み合わせることで、 それらと相互に通信をしたり、制御できるように今後はなっていきます。

そして、そういった流れと共に「人工知能」も驚くほどのスピードで高度化して行っている為、 人が今までやっていた仕事や行動がコンピュータで事足りるようになってくる時代が来ます。

こういった技術発展によって、近い将来に産業構造や生活の変化が凄まじいものになることが予想されています。

ですが、やはり中心となるのはユーザーであり、技術が優れているだけではそのモノは開発する価値はないと思います。 どんな時代になろうと、ユーザーが心から必要とするものを目指して作っていく必要があるんです。

その為に様々な技術を束ね、きちんとユーザーに必要となる内容を統合していく方法として、 UXデザインを学習することは今後ますます必須となってくるのではないでしょうか。


今後ますます注目を集めてくるであろう「UXデザイン」 奥が深いことこの上なしですね。

ほな!

GCP の DataProc で MLlib を使う

はじめに

おはようございます。こんにちは。こんばんわ。

佐々木です。

Google Cloud Platform の DataProc で MLlib を使ってみたのでメモ書きします。

ちなみに機械学習とかは全然疎いです。

DataProc と MLLib

DataProc は Google Cloud Platform にある Spark / Hadoop が使えるマネージサービスです

cloud.google.com

MLLib は Spark に載ってる機械学習用のライブラリです

spark.apache.org

前提

  • Google Cloud Platform の DataProc API を有効にしておく
  • Google Cloud Storage も使っているので有効にしておく
  • gcloud command はインストール済

MLlib の学習用データを作成する

今回 MLlib で扱うデータは BigQuery のデータから抽出します。

今回は MLlib の決定木を使ってみます。

学習用データは csv で入力することにします。

SQLは擬似的なもので、アクセス数と購入の有無を取れるようなイメージです

SELECT
 IF(orders.user_id IS NOT NULL, 1, 0) AS result,
 COUNT(access_logs.user_id) AS cnt
FROM access_logs.access_20160711 access_logs
LEFT OUTER JOIN test.order_log_20160711 orders
  ON access_logs.user_id = orders.user_id
GROUP BY access_logs.user_id

こんな感じの SQL を書いてこれを Google Cloud Storage に export します

MLLib 用の python script を書く

DataProc で用意されていた Python Script をちょっと改修して書きました

#!/usr/bin/python
import pyspark
from pyspark.mllib.regression import LabeledPoint
from pyspark.mllib.tree import DecisionTree, DecisionTreeModel
from pyspark.mllib.util import MLUtils

def parseRow(row):
    tokens = row.split(',')
    label = tokens[0]
    features = tokens[1:]
    return LabeledPoint(label, features)

sc = pyspark.SparkContext()

data = sc.textFile("gs://test/orders.csv")
labeled_points = data.map(parseRow)

(trainingData, testData) = labeled_points.randomSplit([0.7, 0.3])
model = DecisionTree.trainClassifier(trainingData, numClasses=2, categoricalFeaturesInfo={}, impurity='gini', maxDepth=5, maxBins=32)
predictions = model.predict(testData.map(lambda x: x.features))
labelsAndPredictions = testData.map(lambda lp: lp.label).zip(predictions)
testErr = labelsAndPredictions.filter(lambda (v, p): v != p).count() / float(testData.count())
print('Test Error = ' + str(testErr))
print('Learned classification tree model:')
print(model.toDebugString())

DataProc のクラスタを作成する

これは GCP Console でも gcloud command でもどちらでもいいですが、クラスタを作成します

特に何も困らず作成出来ると思います

DataProc に JOB を投げる

作成したクラスタに上記の python script を投げます

$ gcloud dataproc jobs submit pyspark --cluster cluster-1 order.py

DecisionTreeModel classifier of depth 5 with 23 nodes
  If (feature 0 <= 18.0)
   If (feature 0 <= 10.0)
    If (feature 0 <= 4.0)
     If (feature 0 <= 3.0)
      Predict: 0.0
     Else (feature 0 > 3.0)
      Predict: 1.0
    Else (feature 0 > 4.0)
     Predict: 0.0
   Else (feature 0 > 10.0)
    If (feature 0 <= 11.0)
     Predict: 1.0
    Else (feature 0 > 11.0)
     If (feature 0 <= 16.0)
      Predict: 0.0
     Else (feature 0 > 16.0)
      If (feature 0 <= 17.0)
       Predict: 1.0
      Else (feature 0 > 17.0)
       Predict: 0.0
  Else (feature 0 > 18.0)
   If (feature 0 <= 68.0)
    If (feature 0 <= 44.0)
     If (feature 0 <= 37.0)
      If (feature 0 <= 20.0)
       Predict: 0.0
      Else (feature 0 > 20.0)
       Predict: 1.0
     Else (feature 0 > 37.0)
      Predict: 0.0
    Else (feature 0 > 44.0)
     Predict: 1.0
   Else (feature 0 > 68.0)
    Predict: 0.0

うーん。学習用データが少なくてちょっと残念な感じになってしまいました。

もうちょっとデータを増やしてやる必要があるみたいですね。

しかし、今回の目的の DataProc で MLlib を利用して決定木を作成することはできました。

おわりに

DataProc をつかってデータを処理するのは楽しいですね。

DataProc と Bigquery あたりを連携して定常的にデータ分析ができる仕組みを作りたいなと思います。

また何か進捗があったらこのブログで報告させていただければと思います。

ほな!

GCP の StackDriver Logging を使ってエラーログを集める

おはようございます。こんにちは。こんばんわ。

佐々木です。体重は怖くて測ってません。

最近は、暑かったり寒かったり暑かったりと体調を崩しやすい時期ですね。

健康は、日頃のモニタリングが大事です。異常を検知したらすぐに診察をうけるのが一番です。

WEBサービスも一緒です。日々のモニタリングから異常を検知して、早急に対応できる体制を整えましょう。

というわけで(どういうわけ)、最近リリースした WEB API だけのサービスがあるので、ここでエラーのモニタリングを行いましょう。

最初は AWS の CloudWatch を使っていたのですが、いかんせん使いづらいです。

Google Cloud Platform (以下 GCP) で StackDriver Logging のベータ版がリリースされていたので今回はこちらを使ってみます。

StackDriver Logging とは

僕が紹介することではないのでページを御覧ください。

cloud.google.com

ザクッというと、ログをばこっと投げておけばあとは StackDriver の UI とかと連携して見たりすることが出来るようなものっぽいです。

StackDriver は各サービスと連携できるので PagerDuty のようなものとも連携していくことが出来ますね。

便利な予感がします

StackDriver Logging にログを送るために

fluent plugin

今回対象のサービスは AWS の EC2 で動いています。GAE じゃないのが残念。ですが

fluent の plugin で StackDriver Logging にログを送れるプラグインが有りますのでこちらを利用します

github.com

aggregator に install

install

$ sudo td-agent-gem install fluent-plugin-google-cloud

td-agent.conf / aggregator

<match log.error>
  type google_cloud
</match>

forwarder

td-agent.conf / forwarder

<source>
  type tail
  format json
  path /var/log/XXXX.log
  pos_file /tmp/td-agent/XXXX.pos
  tag log.error
</source>

<match log.error>
  type forward

  <server>
    host XXXXXXXXX
    port 24224
  </server>

  heartbeat_type tcp
  flush_interval 10s
  num_threads 8
  expire_dns_cache 600
  buffer_type file
  buffer_path /var/log/td-agent/buffer/log.error
</match>

log format は plugin を見て metadata になりそうな部分を required params として用意しています

{
  time: datetime.to_i,
  path: path,
  severity: severity,
  message: message
}

用意するのはこれだけでOKです

あとは fluentd を restart して設定を反映させましょう

td-agent.log

2016-07-05 09:45:51 +0000 [info]: Successfully sent to Google Cloud Logging API.

こんな感じの info が出てくれば成功です。

それでは StackDriver Logging の画面を見てみましょう

StackDriver Logging UI

↑までやればログが送られてきています

↓は一行のエラーログです。

time, severity, message は metadata として扱われ、

path は structPayload のデータとして扱うことが出来ます。

f:id:sekaie:20160705201245p:plain

まだ全然見てないですがフィルタとかを設定して指定のログだけを見るとかそういうのも出来るみたいです

https://cloud.google.com/logging/docs/view/advanced_filters

さらに他の GCP サービスと連携

せっかくの GCP サービスですし、 BigQuery とかと連携してみましょう

Logging には BigQuery に Streaming Insert する機能があるようです

f:id:sekaie:20160705201831p:plain

ちょこちょこと必要な情報を入れてエクスポートしてみます。

するとこんな感じに BigQuery にテーブルが作成されています

f:id:sekaie:20160705201949p:plain

後はこのテーブルを焼くなり煮るなりしてデータを好きに扱えます。

とても便利ですね。

おわりに

今回は StackDriver Logging にログを貯めるところを中心にご紹介しました。

GCPはデータ分析のためのサービスが豊富にそろっていて、Logとデータベースのデータを連携したりとかが容易にできるようになります。

まだ、GCP を使ったことない人はぜひ使ってみてはいかがでしょうか(営業じゃないです)

ほな!

Vimに移行しようかなって話

f:id:sekaie:20160518181157p:plain

ひよっこデザイナーの寺田です。最近カラオケで歌いすぎて喉をつぶしました。

今日はエディタをVimにしようか迷っていますので(たぶんしない)、 私のようにVimに興味を持たれた方にわかりやすいようにVimの特徴に対して簡単にまとめました。


開発者向けソフトウェアVimとは

Vimは非常に昔からあるソフトウェアで、高機能なことで有名です。 しかしながら、特殊な動作環境の為、使いこなすまでは非常に時間がかかあります。

使いこなしたらもう離れられないらしい。

省エネで高速動作!

CUI(command line interface)で動くので、とにかく軽い!早い! VIMは非常に軽量なソフトウェアである為、少ない資源(CPU/メモリー)で高速に動作するため快適です。

CUIとは簡単に説明するとコマンドラインだけで動く環境のこと。つまりVimにはマウスという概念が存在しません。普段あまり意識をしていないマウス操作も実は結構時間を取られているものです。キーボードだけの操作に乗り換えることで、倍以上の時間短縮も可能といっても過言ではないでしょう。キーボードだけで操作を完結させるのってなんかかっこいいですね。

自由にカスタム!

プラグインがなくても、インデントや改行、タブの設定など、自分で細かな設定を自由にすることが可能。 非常に便利な小技も多数あり。

多機能!

Vimの歴史は非常に長いため、開発コミュニティーが充実しており、 日々新たな追加機能(プラグイン)がアップされており、様々な機能を簡単に拡張することが可能になっています。

Vimプラグインに関してはこういった記事を参考にしてみてください。↓↓↓↓↓

素のVimだと限界がある!絶対に入れておきたいVimプラグイン25個

迅速対応!

新しい形式のフォーマットにもすぐに対応します。

爆速編集!

特殊な操作方法を覚えるのには時間を要するものの、覚えちゃえばこっちのもの。 すさまじいスピードで正確なコーディングをを行うことが可能になります。

みんなが使える!

OSなど環境に左右されない(マルチプラットフォーム)ですので、 Windows, Mac OS X, Linux 様々なプラットフォームで利用可能です。  

デメリットは!?

こんな素晴らしいVimですが、 やはりデメリットといえば、コマンドの難しさでしょう。 最初はマウスが使えないことや、よく使われるショートカットも割り当てがなく、慣れるまで非常に大変です。 使いこなすまでに労力を必要とするので、始めるには勇気が必要ですね。


勇気のある方はぜひVimにトライして快適なコーディングライフを満喫してください。

ほな!