ククログ

株式会社クリアコード > ククログ > SharetaryのためのGitHubアクティビティ定点観測の設定・改

SharetaryのためのGitHubアクティビティ定点観測の設定・改

先日、「GitHub上のアクティビティを定点観測してみませんか?」と題してfluent-plugin-github-activitiesSharetaryという2つのソフトウェアを紹介しましたが、Sharetaryの改善に伴っていくつか設定の仕方に変化がありましたので、改めて、最新バージョンでの推奨設定について解説します。 ClearCode Inc. Organizationに所属しているアカウントの公開アクティビティを収集するSharetaryの運用サンプルも、この解説と同じ手順でSharetary 0.5.0に移行しました。

なお、この記事はSharetaryの利用のための技術情報が主ですが、Fluentdのストリームにおける1つの入力を元にして、fluent-plugin-groongaで複数テーブルにレコードを追加する方法の解説にもなっています。 fluent-plugin-groongaを使ったGroongaサーバーのレプリケーションに対して、in_groongaを使わずに直接レコードを登録するやり方に興味がある方も、参考にしてみて下さい。

Sharetary 0.4.0(0.5.0)での変更点

バージョン0.4.0以降のバージョンには様々な変更点がありますが、最大の変更点はスキーマ定義の変更です。

バージョン0.3.0までではほとんどの情報がEventsテーブルに集中していましたが、これにはデータの重複が増えてしまうという欠点がありました。 また、Eventsテーブルのカラム数が増えれば増えるほど管理が煩雑になってしまうという問題もあります。 そこでバージョン0.4.0からは、イベントに直接関係ない情報は別のテーブルに分けて管理するように改めました。

また、それに伴ってイベントに複数のタグを紐付けられるようにし、イベントの属するscope(GitHubのアクティビティに対応するイベントであれば、リポジトリの情報など)はタグの1つとして管理するようにしました。 これにより、「このイベントはfooというリポジトリに関連付けられており、barというハッカソンの期間中に行われた」というような複数の切り口での分類が可能になりました。

(図:Events, Actors, Tagsの各テーブル同士の関係)

このスキーマ変更によって、これまでにクロール済みのイベント情報はそのままでは使えなくなっています。 後述の手順に則って、データを移行する必要があります。

Sharetary 0.3.0からのアップグレード手順

既に設置済みのSharetaryのバージョンを0.3.0から0.4.0以上に更新する手順は以下の通りです。

  1. SharetaryのHTTPサーバ、クローラを停止する。

  2. スキーマ定義変更およびデータ移行用スクリプトをダウンロードする。

  3. ダウンロードしたmigrate-0.3.0-to-0.4.0を、Bashスクリプトとして実行し、データを移行する。

  4. クローラの設定を、新しいスキーマに合わせて更新する。

  5. クローラの動作を再開させる。

  6. sudo npm install -g sharetaryで最新バージョンのSharetaryをインストールする。

  7. SharetaryのHTTPサーバを起動する。

データ移行用のスクリプトは、以下のオプションを指定できます。

  • -h <hostname> : Groongaサーバ(またはDroongaクラスタ)のホスト名。省略時はlocalhost

  • -p <port> : Groongaサーバ(またはDroongaクラスタ)のHTTPサーバがlistenしているポート番号。省略時は10041

  • -t <追加で設定するタグ> : 移行された全てのイベントに固定で付与するタグ。

  • -d : 指定するとdry-runモードとなり、実際にはデータベースに変更を行わないで、どのような変更が行われるのかをシミュレートする。

例えばGroongaサーバがgroongaというホストの10041番ポートで動作していて、収集済みのイベントに「2015-sezemi-readable-code」というタグを付与して移行する場合、コマンドラインは以下のようになります。

$ wget https://raw.githubusercontent.com/clear-code/sharetary/master/bin/migrate-0.3.0-to-0.4.0
$ chmod +x ./migrate-0.3.0-to-0.4.0
$ ./migrate-0.3.0-to-0.4.0 -h groonga -t 2015-sezemi-readable-code -d

意図しないデータ破壊を避けるためは、まず1回dry-runして、適用される変更を先に把握しておくとよいでしょう。

追加するタグの指定は必須ではありませんが、指定しておくのがお薦めです。 過去の運用で何かのハッカソンに関係するイベントを収集済みなのであれば、そのハッカソンの名前をタグとして追加しておくと、それ以後収集するイベントを古いイベントと区別しやすくなります。

クローラの設定をどのように更新するかは、どんなクローラを使っているかによって変わります。 以下は、先日のエントリで紹介したfluent-plugin-github-activitiesの場合の設定(Fluentdの設定)の解説となります。 設定の参考にしてみて下さい。

Sharetary 0.4.0以降のバージョン向けの、fluent-plugin-github-activitiesの設定

先のエントリでも解説していますが、fluent-plugin-github-activitiesは本質的にはSharetaryとは全く独立した存在です。 fluent-plugin-github-activitiesはGitHubのアクティビティをクロールして取得してきてFluentdのストリームに取り込むだけの物で、それを加工してSharetary用のイベント情報としてデータベースに格納するのは、他のプラグインの仕事という事になります。

ここでは、Sharetaryのリポジトリに含まれている設定例の内容を引き合いに出しながら、fluent-plugin-github-activitiesの出力をどのように加工すればSharetary 0.4.0以降のイベント情報として使えるのかを解説します。

レコードの取得

まず最初にfluent-plugin-github-activities用の<source>の設定ですが、ここは先のエントリで紹介した通りで変化はありません。

<source>
  type github-activities
  access_token access-token-of-github
  users ashie,cosmo0920,kenhys,kou,min-shin,myokoym,okkez,piroor
  clients 4
  interval 1
  base_tag github-activity.
  pos_file /var/log/td-agent/github-activities.json
</source>

これによってレコードとして取り込まれたアクティビティ情報を加工する指定が、この後に続く事になります。

レコードを「イベント情報用」「人物用」「タグ用」の3つに複製し、ストリームを分岐する

FluentdでSharetary用のデータベースにレコードを格納するにはfluent-plugin-groongaを使いますが、fluent-plugin-groonga、特にその中でFluentdのストリームからGroongaサーバへの書き込みを行うout_groongaは、流入してきたレコードを特定のテーブル1つのレコードとして格納するという物です。

しかしSharetary 0.4.0以降用には、1つのイベントにつき、イベント情報そのものを格納するEventsテーブル、人物のメタ情報を格納するActorsテーブル、タグのメタ情報を格納するTagsテーブルという具合に、最大で3つのテーブルに同時にレコードを追加する必要があります。

(図:Events, Actors, Tagsの各テーブル同士の関係)

そこで、ストリームを「イベント用」「人物用」「タグ用」の3つに分岐して、それぞれ別々の設定のfluent-plugin-groongaによってレコードとして各テーブルに格納することになります。

(図:Events, Actors, Tagsの各テーブル用にストリームを分岐する様子)

このようなストリームの分岐には、Fluentdに標準添付されているcopyというプラグインを使います。

<match github-activity.**>
  type copy

  # Eventsテーブル用のレコード
  <store>
    type        record_reformer
    enable_ruby false
    tag         event.${tag}
  </store>

  # Actorsテーブル用のレコード
  <store>
    type        record_reformer
    enable_ruby false
    tag         actor.${tag}
  </store>

  # Tagsテーブル用のレコード
  <store>
    type        record_reformer
    enable_ruby false
    tag         repository-tag.${tag}
  </store>
</match>

copyプラグインは、<store>に書かれた別のプラグイン用の指定に基づいて加工を行ったレコードを、Fluentdのストリームに出力します。 この例では、レコードを加工するプラグインであるfluent-plugin-record-reformerを使って、それぞれのタグ名を「何に使うためのレコードか?」という事を示す物に変えてから出力しています。 3つの<store>が書かれているため、これでストリームは3つに分かれることになります。

人物用のレコードを作成し、Actorsテーブルに格納する

話を単純にするために、外部テーブルの方から解説していきます。 まずはActorsテーブルです。

このテーブルのレコードは_keyが人物の名前で、その人物のプロフィールページのURIとなるuri、アイコン画像のicon、人物の重要度を示すclassの3つのフィールドを持ちます。

copyプラグインによって分岐された3つのストリームのうち、Actorsテーブル用に出力しているレコードについて、fluent-plugin-record-reformerの変換ルールを以下のように更新し、上記のフィールドを持ったレコードを出力するようにします。

<match github-activity.**>
  type copy
  ...
  # Actorsテーブル用のレコード
  <store>
    type         record_reformer
    enable_ruby  true
    renew_record true
    tag          sharetary.actor
    <record>
      _key  ${(actor || committer)["login"]}
      uri   https://github.com/${(actor || committer)["login"]}/
      icon  ${self["$github-activities-related-avatar"]}
      class major
    </record>
  </store>
  ...
</match>

この時の設定のポイントは以下の通りです。

  • Acotrsテーブル用のレコードはゼロから組み立てるので、renew_record trueとして、加工元レコードのフィールドを引き継がないようにしています。

  • enable_ruby trueは、セキュリティや速度などの点でデメリットがありますが、今回の用途では必要な設定です。 というのも、fluent-plugin-record-reformerは、プレースホルダーを使って加工元のレコードのフィールドの値を参照できますが、fluent-plugin-github-activitiesが出力するレコード(GitHubのAPIが返すJSONそのままの形式)のようにそれぞれのフィールドが階層化されている場合、欲しい情報を取り出す事ができません。 ですので、必要な情報を参照できるようにするために、この設定を有効化しています。

  • Actorsテーブル用のレコードにはアクティビティの種類を示す情報は必要なくなるので、タグはsharetary.actorに統一しています。

  • 出力するレコードのフィールドのうち_keyuriは、どちらも元のレコードに含まれているユーザアカウント名を使いたいのですが、個々のコミットに対応するレコードと、それ以外のアクティビティのレコードとでは、持っている情報の構成が若干異なるため、参照先を決め打ちできません。 ですので、ここでは||を使って、レコードに存在する方のフィールドを取り出しています。

  • アイコン画像のURIを参照するために、fluent-plugin-github-activitiesが独自に出力している$github-activities-related-avatarというフィールドを参照していますが、値を参照するために${$github-activities-related-avatar}と書くとエラーになってしまいます。これは、フィールド名の先頭の$が特別な意味を持ってしまうためです。ここでは、各フィールドの値を保持している名前空間オブジェクトのOpenStruct自身の[]メソッドを明示的に呼び出す事で、フィールドの値を参照しています。

  • classフィールドの値は、簡単のためmajorに決め打ちしています。元レコードの情報に基づいてclassの値を適宜切り替えると、「受講者」と「メンター」のように、人物によってイベントの表示の仕方に強弱を付ける事もできます。

次は、できあがったレコードをfluent-plugin-groongaを使ってActorsテーブルに格納するための設定です。

<match sharetary.actor>
  type groonga
  store_table Actors

  protocol http
  host localhost

  buffer_type file
  buffer_path /var/spool/td-agent/buffer/groonga-sharetary-actor
  flush_interval 1s

  <table>
    name Actors
    flags TABLE_HASH_KEY
    key_type ShortText
  </table>

  <mapping>
    name uri
    type ShortText
  </mapping>

  <mapping>
    name icon
    type ShortText
  </mapping>

  <mapping>
    name class
    type ShortText
  </mapping>
</match>
  • このテーブルの情報はSharetaryでは直接検索する対象にはしないので、インデックスは作っていません。

  • buffer_pathに指定するパスは、この設定のための固有のパスにする必要があります。 他のテーブル用のfluent-plugin-groongaの設定との間でこの設定の値が衝突すると、どちらか片方の設定しか有効化されませんので、注意して下さい。

これで、人物の情報がアイコン画像のURIなどのメタ情報を伴って保存されるようになります。

タグ用のレコードを作成し、Tagsテーブルに格納する

人物の次は、イベントのタグ付けのためのタグそのものを格納するTagsテーブルです。

fluent-plugin-github-activitiesで取得したアクティビティから取り出せる情報を使って適切なタグを自動設定すれば、収集したイベントを効率よく分類できるようになります。 最もベタな例は、「そのアクティビティに関連しているリポジトリ」という切り口でのタグ付けでしょう。

このテーブルのレコードは_keyがタグの名前で、タグ固有のアイコン画像を示すiconというフィールドを持ちます。 copyプラグインによって分岐された3つのストリームのうち、Tagsテーブル用に出力しているレコードについて、fluent-plugin-record-reformerの変換ルールを以下のように更新し、上記のフィールドを持った「そのアクティビティに関連しているリポジトリ」のタグにあたるレコードを出力するようにします。

<match github-activity.**>
  type copy
  ...
  # Tagsテーブル用のレコード
  <store>
    type         record_reformer
    enable_ruby  true
    renew_record true
    tag          sharetary.tag
    <record>
      _key  ${tag.end_with?(".commit") ? url.match(/repos\/([^\/]+\/[^\/]+)\/commits/)[1] : tag.end_with?(".fork") ? payload["forkee"]["full_name"] : repo["name"]}
      icon  ${self["$github-activities-related-organization-logo"]}
    </record>
  </store>
</match>
  • Acotrsテーブル用のレコードと同様に、Tags用のレコードもゼロから組み立てるので、renew_record trueとしています。

  • 先述の通り、複雑な構造のレコードから必要な情報を取り出す必要があるので、enable_ruby trueとしています。

  • Tagsテーブル用のレコードにもアクティビティの種類を示す情報は不要なので、タグはsharetary.tagに統一しています。

  • 出力するレコードのフィールドのうち_keyの値は、ほとんどのアクティビティではrepo["name"]で参照できますが、コミットに対応するレコードとForkに対応するレコードだけは違う値を使う必要があります。ここでは、3項演算子を使って、元レコードのどのフィールドの値を使うかを振り分けています。

次は、できあがったレコードをfluent-plugin-groongaを使ってTagsテーブルに格納するための設定です。

<match sharetary.tag>
  type groonga
  store_table Tags

  protocol http
  host localhost

  buffer_type file
  buffer_path /var/spool/td-agent/buffer/groonga-sharetary-tag
  flush_interval 1s

  <table>
    name Tags
    flags TABLE_HASH_KEY
    key_type ShortText
  </table>

  <mapping>
    name icon
    type ShortText
  </mapping>
</match>
  • このテーブルもSharetaryでは検索対象にしないので、インデックスは作っていません。

  • 先述の通り、buffer_pathに指定するパスはこの設定のための固有のパスにする必要があります。

これで、タグの情報も保存できるようになりました。

イベント用のレコードを作成し、Eventsテーブルに格納する

最後に、イベントそのものの情報を格納するEventsテーブルです。

GitHubのアクティビティは様々な種類があるため、Sharetary用のイベント情報に変換するためのルールはアクティビティの種類分だけ定義する必要があります。 全てのアクティビティについて完全な変換ルールを定義するのは煩雑なので、共通化できる所はなるべく共通化する方向で設定を組み立てていく事にします。

共通フィールドを埋める

まず最初に、多くのアクティビティに共通している情報を使って共通のフィールドを埋めます。

copyプラグインによって分岐された3つのストリームのうち、Eventsテーブル用に出力しているレコードについて、fluent-plugin-record-reformerの変換ルールを以下のように更新し、共通のフィールドを埋めた状態でレコードを出力するようにします。

<match github-activity.**>
  type copy

  # Eventsテーブル用のレコード
  <store>
    type        record_reformer
    enable_ruby true
    tag         event.${tag}
    <record>
      type        ${tag_suffix[-1]}
      actor       ${actor && actor["login"]}
      source_icon https://github.com/favicon.ico
      timestamp   ${created_at}
      created_at  ${time}
      _repository ${repo && repo["name"]}
    </record>
  </store>
  ...
</match>

設定のポイントは以下の通りです。

  • この後でアクティビティごとに個別の変換ルールを適用するにあたって、元のレコードの各フィールドをその時に参照したいので、今度はrenew_record trueは指定していません。 <record>で定義した各フィールドは、元のレコードへのフィールド追加、または同名フィールドの値の置き換えになります。

  • イベントの種類を示すtypeフィールドの値は、fluent-plugin-github-activitiesが出力したレコードがgithub-activity.pushのようなタグになっている事を利用して、タグの最後のパートをそのまま使います。 tag_suffix[-1]というプレースホルダを使うと、タグ名の最後のパートを簡単に参照できます。

  • イベントの主体となった人物を示すactorフィールドの値はActorsテーブルに格納したレコードの_keyと同じ値を設定する必要があります。 大多数のアクティビティではこれはactor["login"]の値ですが、個々のコミットに対応するレコードでだけは、違うフィールドを参照しなくてはなりません。 そのような特例については、個々のコミットに対応するレコードの変換ルールを定義するときにまとめて処理する事にして、ここではシンプルに「フィールドを参照できるならその値を使い、参照できなければnilにしておく」という書き方にしています。

  • イベントの由来となっているサービスを表すsource_iconの値は、GitHubのfaviconのURIで決め打ちにしています。 他のサービス由来のイベントも収集する場合は、適切な値をその都度指定しましょう。

  • イベントの日時を示すtimestampフィールドの値は、元レコードのcreated_atの値があればそれを使い、無ければnilにするという書き方にしています。 これも、例外となるアクティビティについては別途値を設定します。

  • イベント情報が記録された日時を示すcreated_atフィールドの値は、現在時刻の代替として、Fluentdのレコードに紐付けられている日時情報を参照しています。 (※元レコードのcreated_atと名前が同じですが、意味合いが異なる物で、こちらはあくまでSharetary用のEventsテーブルのカラム名です。)

  • イベントへのタグ付けのために、Tagsテーブルに格納したレコードの_keyと同じ値をtagsフィールドに設定する必要があります。 これもactor同様に、アクティビティの種類によって参照先のフィールドを変えなくてはなりません。 ただ、tagsフィールドの値は後から少し加工をしたいので、ここでは一旦_repositoryという仮のフィールドに値を設定するに留めています。 (後加工の段階で、これを使ってtagsフィールドの値を埋める事になります。)

アクティビティの種類ごとに固有のフィールドを埋める

次に、個々のアクティビティ用の変換ルールを定義します。

例えば、git pushに対応するイベントの変換ルールは、fluent-plugin-record-reformerを使って以下のように書けます。

<match event.github-activity.push>
  type         record_reformer
  enable_ruby  true
  renew_record true
  keep_keys    type,actor,source_icon,timestamp,created_at,_repository
  tag          sharetary.event
  <record>
    _key        https://github.com/${repo["name"]}/compare/${payload["before"]}...${payload["head"]}
    class       minor
    title       Push
    description Pushed ${payload["size"].to_s} commits to ${repo["name"]}
    uri         https://github.com/${repo["name"]}/compare/${payload["before"]}...${payload["head"]}
    reply_uri   https://github.com/${repo["name"]}/compare/${payload["before"]}...${payload["head"]}#commits_bucket
  </record>
</match>
  • この段階では共通のフィールドが埋まった状態のレコードが渡ってくるため、ここではpushに固有の情報を埋めるだけの変換ルールになっています。

  • Eventsテーブル用のレコードはfluent-plugin-github-activitiesが出力するレコードとは全く異なる形式になるため、renew_record trueとして、ゼロからレコードを組み立てるようにしています。 ただし、前の段階ですでに加工を終えた共通のフィールドについてだけは、keep_keys type,actor,source_icon,timestamp,created_at,_repositoryとして値を引き継いでいます。 このようにする事で、「前の段階で共通のフィールドを埋めておいて、この段階では固有のフィールドだけを埋める」という効率の良い設定が可能となります。

  • Eventsテーブル用のレコードとして形式を変換済みということで、タグはsharetary.eventに統一しています。

  • push以外にも、Issueの投稿、コメントの投稿など、多くのアクティビティの変換ルールは同様の要領で定義する事ができます。

別の例として、git commitに対応するイベントの変換ルールも示します。

<match event.github-activity.commit>
  type         record_reformer
  enable_ruby  true
  renew_record true
  keep_keys    type,source_icon,created_at
  tag          sharetary.event
  <record>
    _key        ${html_url}
    class       normal
    title       Commit ${stats["total"].to_s} changes
    description ${commit["message"]}
    extra_description ${files.collect{|file| "#{file["filename"]} (#{file["status"]})" }.join("\n, ")}\n\n${files.collect{|file| file["patch"] }.join("\n\n")}
    actor       ${committer["login"]}
    uri         ${html_url}
    reply_uri   ${html_url}#new_commit_comment_field
    timestamp   ${commit["committer"]["date"]}
    parent      ${self["$github-activities-related-event"] && "https://github.com/#{self["$github-activities-related-event"]["repo"]["name"]}/compare/#{self["$github-activities-related-event"]["payload"]["before"]}...#{self["$github-activities-related-event"]["payload"]["head"]}" || "" }
    _repository ${url.match(/repos\/([^\/]+\/[^\/]+)\/commits/)[1]}
  </record>
</match>
  • 基本的にはpushの場合と同じなのですが、keep_keysでそのまま流用している共通フィールドが、type,source_icon,created_atだけになっています。 これは、commitのイベントの元となるGitHub APIの戻り値が、ここまでで参照してきたアクティビティの共通フォーマットとは異なる形式を取っているからです。 actor, timestamp, _repositoryの各フィールドの値は、ここで改めて、commit専用のフォーマットになっているレコードから適切な値を参照するようにしています。

Sharetaryリポジトリにある完全版の設定ファイルのサンプルには、fluent-plugin-github-activitiesが対応している他のアクティビティも含めた全ての変換ルールが記述されています。 そちらも併せてご参照下さい。

データベース格納前の微調整を行う

アクティビティごとの変換を終えたら、今度はレコードの内容の微調整のための後処理を行います

まず、仮フィールドの_repositorytagsフィールドに変換して、イベントをタグ付けします。 これは、Fluentdに標準添付のrecord_transformerプラグインを使って、以下のような<filter>で実現できます。

<filter sharetary.event>
  type        record_transformer
  enable_ruby false
  remove_keys _repository
  <record>
    tags ["${_repository}"]
  </record>
</filter>

record_transformerの設定は、元になったfluent-plugin-record-reformerと同じような書式で記述します。

  • tagsフィールドの値を、_repositoryフィールドの値が単一の要素になっている配列として定義しています。

  • それと同時に、不要になった仮フィールドの_repositoryを、remove_keys _repositoryでレコードから削除しています。

これだけだと、この段階で変換を行う意味はあまり無いように見えます。 実際、共通フィールドを埋める段階や、各アクティビティ固有のフィールドを埋める段階でも、tagsフィールドを配列として定義することは可能です。

しかし、このようにtagsフィールドの変換を最後の段階に分けておくと、元の情報に含まれていなかった情報を使った、固定のタグの追加が可能になります。 例えば下のようにすれば、各イベントには関連するリポジトリ名のタグだけでなく、sezemi-2015-readable-codeというタグも固定で付与されるようになります。

<filter sharetary.event>
  type         record_transformer
  enable_ruby  false
  remove_keys  _repository
  <record>
    tags ["${_repository}", "sezemi-2015-readable-code"]
  </record>
</filter>

SEゼミの2015年度の取り組みでは4つのサブイベントを開催しますが、サブイベントの名前のタグをこのようにして自動付与すれば、後からサブイベントごとの情報を効率よく検索できるようになります。 また、1つのサブイベントが終わったら上記の後加工段階のフィルタだけを設定し直す事で、参加メンバーが同じだとしても、別のサブイベントの情報を簡単に識別できます。

(最初からtagsフィールドを配列型にしておいて、後処理の段階でtagsの配列に要素を追加する、という形にできればそれが最もスマートなのですが、残念ながら、そのような変換を行えるFluentdプラグインは現時点では無い模様です……そこで、次善の策としてこのようなやり方を考えてみた次第です。)

タグ付けが終わったら、最後の仕上げとして、日時を示すフィールドの値をunixtimeを表す整数値に変換します。 これは、fluent-plugin-filter_typecastプラグインを使って以下のように実現できます。

<filter sharetary.event>
  type  typecast
  types timestamp:time,created_at:time
</filter>

これによって、timestampcreated_atのフィールドの値が、2015-06-15T00:00:00のような文字列から、対応するUTCのunixtimeに変換されます。 Groongaでは日時はunixtimeの整数で表現されますので、この変換は必ず行わなくてはなりません。 (でないと、日付の範囲を指定した絞り込みができません。)

イベント情報をEventsテーブルに格納する

後処理を終えて全てのフィールドが揃ったら、後はEventsテーブルにレコードを格納するだけです。

<match sharetary.event>
  type groonga
  store_table Events

  protocol http
  host localhost

  buffer_type file
  buffer_path /var/spool/td-agent/buffer/groonga-sharetary-event
  flush_interval 1s

  <table>
    name Events
    flags TABLE_HASH_KEY
    key_type ShortText
  </table>

  <table>
    name Timestamps
    flags TABLE_PAT_KEY
    key_type Time
  </table>

  <table>
    name Tags
    flags TABLE_HASH_KEY
    key_type ShortText
  </table>

  <table>
    name Actors
    flags TABLE_HASH_KEY
    key_type ShortText
  </table>

  <table>
    name Terms
    flags TABLE_PAT_KEY
    key_type ShortText
    default_tokenizer TokenBigram
    normalizer NormalizerAuto
  </table>

  <mapping>
    name type
    type ShortText
  </mapping>

  <mapping>
    name class
    type ShortText
  </mapping>

  <mapping>
    name title
    type ShortText
    <index>
      table Terms
      name Events_title_index
      flags WITH_POSITION
    </index>
  </mapping>

  <mapping>
    name description
    type Text
    <index>
      table Terms
      name Events_description_index
      flags WITH_POSITION
    </index>
  </mapping>

  <mapping>
    name extra_description
    type Text
    <index>
      table Terms
      name Events_extra_description_index
      flags WITH_POSITION
    </index>
  </mapping>

  <mapping>
    name tags
    type Tags
    <index>
      table Tags
      name Events_tags_index
    </index>
  </mapping>

  <mapping>
    name uri
    type ShortText
    <index>
      table Terms
      name Events_uri_index
      flags WITH_POSITION
    </index>
  </mapping>

  <mapping>
    name source_icon
    type ShortText
  </mapping>

  <mapping>
    name reply_uri
    type ShortText
  </mapping>

  <mapping>
    name actor
    type Actors
    <index>
      table Actors
      name Events_actor_index
    </index>
  </mapping>

  <mapping>
    name timestamp
    type Time
    <index>
      table Timestamps
      name Events_timestamp_index
    </index>
  </mapping>

  <mapping>
    name created_at
    type Time
    <index>
      table Timestamps
      name Events_created_at_index
    </index>
  </mapping>

  <mapping>
    name parent
    type ShortText
    <index>
      table Terms
      name Events_parent_index
      flags WITH_POSITION
    </index>
  </mapping>
</match>
  • buffer_pathに指定するパスをこの設定のための固有のパスにしている点に注意して下さい。

  • 処理の進行状況によっては、人物やタグのレコードが登録される前にイベントのレコードが登録される事があり得ます。 そのような場合も想定して、ここには外部の参照先であるActorsTagsの両テーブルの定義も含めています。

まとめ

ここまでで設定したすべてのプラグインの関係を図にすると、以下のようになります。

(図:登場した全てのプラグインの関係)

以上、Sharetary 0.3.0をSharetary 0.4.0以降にバージョンアップする際の手順と、Sharetary 0.4.0以降向けにGitHubのアクティビティをクロールするためのFluentdの設定の仕方を解説しました。 その中で、Fluentdのストリームから1つの入力を分岐して複数テーブルにレコードを追加するfluent-plugin-groonga向けの設定の仕方も解説しました。

先日のリーダブルコード勉強会ではまだお試し運用でしたが、今月27日のOSS Hack 4 Beginners来月に予定されているOSS Hack Weekendでは、会場内で行われる開発の様子を横断して眺められることでしょう。 これらのイベントに参加を予定されている方は、会場内のサブスクリーンにもご注目ください。

また、クリアコード関係者の公開アクティビティを収集しているSharetary運用サンプルも引き続き運用しております。 クリアコードの普段の開発の様子も是非ご覧になってみて下さい。