# requires fluent-plugin-github-activities # for students type github-activities # Authentication is strongly recommended, because there is a rate limit: 60requests/hour by default. # With authentication, it becomes 5000requests/hour (means about 80requests/minute). # See following the GitHub help about access_token # https://help.github.com/articles/creating-an-access-token-for-command-line-use/ access_token access-token-of-github users min-shin,myokoym,okkez,piroor include_foreign_commits true clients 3 interval 2 base_tag github-activity.student. pos_file /var/log/td-agent/github-activities-student.json # for mentors type github-activities access_token access-token-of-github users ashie,cosmo0920,kenhys,kou include_foreign_commits true clients 2 interval 2 base_tag github-activity.mentor. pos_file /var/log/td-agent/github-activities-mentor.json # copy record for event, tag, and actor (requires fluent-plugin-record-reformer) type copy type record_reformer enable_ruby false tag event.${tag} type record_reformer enable_ruby false tag repository-tag.${tag} type record_reformer enable_ruby false tag actor.${tag} # mapping rules for events (requires fluent-plugin-map) ## commit and push type map # You cannot define a string literal starting with double quote directly... tag "\"sharetary.\" + tag" time time # You cannot use embedding patterns like "prefix #{variable}" because fluentd recognizes "#" mark next to a whitespace as the start of the comment of the line. # Instead you must use concatenation of strings like: '"prefix " + variable' record (require("time") || true) && { "_key" => "https://github.com/#{record["repo"]["name"]}/compare/#{record["payload"]["before"]}...#{record["payload"]["head"]}", "class" => "minor", "tags" => [record["repo"]["name"]], "title" => "Push", "description" => "Pushed " + record["payload"]["size"].to_s + " commits to " + record["repo"]["name"], "actor" => record["actor"]["login"], "uri" => "https://github.com/#{record["repo"]["name"]}/compare/#{record["payload"]["before"]}...#{record["payload"]["head"]}", "reply_uri" => "https://github.com/#{record["repo"]["name"]}/compare/#{record["payload"]["before"]}...#{record["payload"]["head"]}#commits_bucket", "created_at" => Time.now.to_i, "timestamp" => Time.parse(record["created_at"]).to_i, "parent" => nil } type map tag "\"sharetary.\" + tag" time time record (require("time") || true) && { "_key" => record["html_url"], "class" => "normal", "tags" => [record["url"].match(/repos\/([^\/]+\/[^\/]+)\/commits/)[1]], "title" => "Commit " + record["stats"]["total"].to_s + " changes", "description" => record["commit"]["message"], "extra_description" => record["files"].collect{|file| "#{file["filename"]} (#{file["status"]})" }.join("\n, ") + "\n\n" + record["files"].collect{|file| file["patch"] }.join("\n\n"), "actor" => record["committer"]["login"], "uri" => record["html_url"], "reply_uri" => "#{record["html_url"]}#new_commit_comment_field", "created_at" => Time.now.to_i, "timestamp" => Time.parse(record["commit"]["committer"]["date"]).to_i, "parent" => record["$github-activities-related-event"] && "https://github.com/#{record["$github-activities-related-event"]["repo"]["name"]}/compare/#{record["$github-activities-related-event"]["payload"]["before"]}...#{record["$github-activities-related-event"]["payload"]["head"]}" || nil } ## comments on commits type map tag "\"sharetary.\" + tag" time time record (require("time") || true) && { "_key" => record["payload"]["comment"]["html_url"], "class" => "major", "tags" => [record["repo"]["name"]], "title" => "Commented to the commit " + record["repo"]["name"] + "/#{record["payload"]["comment"]["commit_id"]}", "description" => record["payload"]["comment"]["body"], "actor" => record["actor"]["login"], "uri" => record["payload"]["comment"]["html_url"], "reply_uri" => "#{record["payload"]["comment"]["html_url"].split("#").first}#new_commit_comment_field", "created_at" => Time.now.to_i, "timestamp" => Time.parse(record["created_at"]).to_i, "parent" => record["payload"]["comment"]["html_url"].split("#").first } ## issues type map tag "\"sharetary.\" + tag" time time record (require("time") || true) && { "_key" => record["payload"]["issue"]["html_url"], "class" => "major", "tags" => [record["repo"]["name"]], "title" => "Open", "description" => "Opened new issue: " + "#" + record["payload"]["issue"]["number"].to_s + " " + record["payload"]["issue"]["title"] + ": " + (record["payload"]["issue"]["body"] || ""), "actor" => record["actor"]["login"], "uri" => record["payload"]["issue"]["html_url"], "reply_uri" => "#{record["payload"]["issue"]["html_url"].split("#").first}#new_comment_field", "created_at" => Time.now.to_i, "timestamp" => Time.parse(record["created_at"]).to_i, "parent" => nil } type map tag "\"sharetary.\" + tag" time time record (require("time") || true) && { "_key" => record["payload"]["issue"]["html_url"] + "#" + Time.parse(record["payload"]["issue"]["updated_at"]).to_i.to_s, "class" => "major", "tags" => [record["repo"]["name"]], "title" => "Close", "description" => "Closed the issue: " + "#" + record["payload"]["issue"]["number"].to_s + " " + record["payload"]["issue"]["title"], "actor" => record["actor"]["login"], "uri" => record["payload"]["issue"]["html_url"], "reply_uri" => "#{record["payload"]["issue"]["html_url"].split("#").first}#new_comment_field", "created_at" => Time.now.to_i, "timestamp" => Time.parse(record["created_at"]).to_i, "parent" => record["payload"]["issue"]["html_url"] } type map tag "\"sharetary.\" + tag" time time record (require("time") || true) && { "_key" => record["payload"]["issue"]["html_url"] + "#" + Time.parse(record["payload"]["issue"]["updated_at"]).to_i.to_s, "class" => "major", "tags" => [record["repo"]["name"]], "title" => "Reopen", "description" => "Reopened the issue: " + "#" + record["payload"]["issue"]["number"].to_s + " " + record["payload"]["issue"]["title"], "actor" => record["actor"]["login"], "uri" => record["payload"]["issue"]["html_url"], "reply_uri" => "#{record["payload"]["issue"]["html_url"].split("#").first}#new_comment_field", "created_at" => Time.now.to_i, "timestamp" => Time.parse(record["created_at"]).to_i, "parent" => record["payload"]["issue"]["html_url"] } type map tag "\"sharetary.\" + tag" time time record (require("time") || true) && { "_key" => record["payload"]["comment"]["html_url"], "class" => "major", "tags" => [record["repo"]["name"]], "title" => "Comment to " + "#" + record["payload"]["issue"]["number"].to_s + " " + record["payload"]["issue"]["title"], "description" => record["payload"]["comment"]["body"], "actor" => record["actor"]["login"], "uri" => record["payload"]["comment"]["html_url"], "reply_uri" => "#{record["payload"]["comment"]["html_url"].split("#").first}#new_comment_field", "created_at" => Time.now.to_i, "timestamp" => Time.parse(record["created_at"]).to_i, "parent" => record["payload"]["issue"]["html_url"] } ## pull requests type map tag "\"sharetary.\" + tag" time time record (require("time") || true) && { "_key" => record["payload"]["pull_request"]["html_url"], "class" => "important", "tags" => [record["repo"]["name"]], "title" => "PR", "description" => "Created new pull-request: " + "#" + record["payload"]["pull_request"]["number"].to_s + " " + record["payload"]["pull_request"]["title"] + ": " + (record["payload"]["pull_request"]["body"] || ""), "actor" => record["actor"]["login"], "uri" => record["payload"]["pull_request"]["html_url"], "reply_uri" => "#{record["payload"]["pull_request"]["html_url"].split("#").first}#new_comment_field", "created_at" => Time.now.to_i, "timestamp" => Time.parse(record["created_at"]).to_i, "parent" => nil } type map tag "\"sharetary.\" + tag" time time record (require("time") || true) && { "_key" => record["payload"]["pull_request"]["html_url"] + "#" + Time.parse(record["payload"]["pull_request"]["updated_at"]).to_i.to_s, "class" => "important", "tags" => [record["repo"]["name"]], "title" => "PR Reopen", "description" => "Reopened the pull-request " + "#" + record["payload"]["pull_request"]["number"].to_s + " " + record["payload"]["pull_request"]["title"], "actor" => record["actor"]["login"], "uri" => record["payload"]["pull_request"]["html_url"], "reply_uri" => "#{record["payload"]["pull_request"]["html_url"].split("#").first}#new_comment_field", "created_at" => Time.now.to_i, "timestamp" => Time.parse(record["created_at"]).to_i, "parent" => record["payload"]["pull_request"]["html_url"] } type map tag "\"sharetary.\" + tag" time time record (require("time") || true) && { "_key" => record["payload"]["pull_request"]["html_url"] + "#" + Time.parse(record["payload"]["pull_request"]["updated_at"]).to_i.to_s, "class" => "important", "tags" => [record["repo"]["name"]], "title" => "PR Merge", "description" => "Merged the pull-request \"#" + record["payload"]["pull_request"]["number"].to_s + " " + record["payload"]["pull_request"]["title"], "actor" => record["actor"]["login"], "uri" => record["payload"]["pull_request"]["html_url"], "reply_uri" => "#{record["payload"]["pull_request"]["html_url"].split("#").first}#new_comment_field", "created_at" => Time.now.to_i, "timestamp" => Time.parse(record["created_at"]).to_i, "parent" => record["payload"]["pull_request"]["html_url"] } type map tag "\"sharetary.\" + tag" time time record (require("time") || true) && { "_key" => record["payload"]["pull_request"]["html_url"] + "#" + Time.parse(record["payload"]["pull_request"]["updated_at"]).to_i.to_s, "class" => "important", "tags" => [record["repo"]["name"]], "title" => "PR Cancel", "description" => "Cancelled the pull-request \"#" + record["payload"]["pull_request"]["number"].to_s + " " + record["payload"]["pull_request"]["title"], "actor" => record["actor"]["login"], "uri" => record["payload"]["pull_request"]["html_url"], "reply_uri" => "#{record["payload"]["pull_request"]["html_url"].split("#").first}#new_comment_field", "created_at" => Time.now.to_i, "timestamp" => Time.parse(record["created_at"]).to_i, "parent" => record["payload"]["pull_request"]["html_url"] } type map tag "\"sharetary.\" + tag" time time record (require("time") || true) && { "_key" => record["payload"]["comment"]["html_url"], "class" => "important", "tags" => [record["repo"]["name"]], "title" => "PR Comment " + "#" + record["payload"]["issue"]["number"].to_s + " " + record["payload"]["issue"]["title"], "description" => record["payload"]["comment"]["body"], "actor" => record["actor"]["login"], "uri" => record["payload"]["comment"]["html_url"], "reply_uri" => "#{record["payload"]["comment"]["html_url"].split("#").first}#new_comment_field", "created_at" => Time.now.to_i, "timestamp" => Time.parse(record["payload"]["comment"]["created_at"]).to_i, "parent" => record["payload"]["issue"]["pull_request"]["html_url"] } ## fork type map tag "\"sharetary.\" + tag" time time record (require("time") || true) && { "_key" => record["payload"]["forkee"]["html_url"] + "#forked", "class" => "normal", "tags" => [record["payload"]["forkee"]["full_name"]], "title" => "Fork", "description" => "Forked the repository " + record["repo"]["name"] + " to " + record["payload"]["forkee"]["full_name"], "actor" => record["actor"]["login"], "uri" => record["payload"]["forkee"]["html_url"] + "#forked", "reply_uri" => nil, "created_at" => Time.now.to_i, "timestamp" => Time.parse(record["created_at"]).to_i, "parent" => nil } ## branch, tag type map tag "\"sharetary.\" + tag" time time record (require("time") || true) && { "_key" => "https://github.com/" + record["repo"]["name"] + "/tree/" + record["payload"]["ref"], "class" => "normal", "tags" => [record["repo"]["name"]], "title" => "Branch", "description" => "Created new branch " + record["payload"]["ref"] + " at the repository " + record["repo"]["name"], "actor" => record["actor"]["login"], "uri" => "https://github.com/" + record["repo"]["name"] + "/tree/" + record["payload"]["ref"], "reply_uri" => nil, "created_at" => Time.now.to_i, "timestamp" => Time.parse(record["created_at"]).to_i, "parent" => nil } type map tag "\"sharetary.\" + tag" time time record (require("time") || true) && { "_key" => "https://github.com/" + record["repo"]["name"] + "/tree/" + record["payload"]["ref"], "class" => "normal", "tags" => [record["repo"]["name"]], "title" => "Tag", "description" => "Created new tag " + record["payload"]["ref"] + " at the repository " + record["repo"]["name"], "actor" => record["actor"]["login"], "uri" => "https://github.com/" + record["repo"]["name"] + "/tree/" + record["payload"]["ref"], "reply_uri" => nil, "created_at" => Time.now.to_i, "timestamp" => Time.parse(record["created_at"]).to_i, "parent" => nil } # complete common fields (requires fluent-plugin-record-reformer) type record_reformer enable_ruby false tag completed.${tag} type ${tag_parts[4]} source_icon https://github.com/favicon.ico # complete common fields and adding extra tag (requires fluent-plugin-map) # # type map # tag "\"completed.\" + tag" # time time # record (record.merge("type" => tag.split(".")[4], "source" => "https://github.com/favicon.ico", "tags => record["tags"] + ["sample"])) # # storing event into Groonga's database (requires fluent-plugin-groonga) 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 name Events flags TABLE_HASH_KEY key_type ShortText
name Timestamps flags TABLE_PAT_KEY key_type Time
name Tags flags TABLE_HASH_KEY key_type ShortText
name Actors flags TABLE_HASH_KEY key_type ShortText
name Terms flags TABLE_PAT_KEY key_type ShortText default_tokenizer TokenBigram normalizer NormalizerAuto
name type type ShortText name class type ShortText name title type ShortText table Terms name Events_title_index flags WITH_POSITION name description type Text table Terms name Events_description_index flags WITH_POSITION name extra_description type Text table Terms name Events_extra_description_index flags WITH_POSITION name tags type Tags table Tags name Events_tags_index name uri type ShortText table Terms name Events_uri_index flags WITH_POSITION name source_icon type ShortText name reply_uri type ShortText name actor type Actors table Actors name Events_actor_index name timestamp type Time table Timestamps name Events_timestamp_index name created_at type Time table Timestamps name Events_created_at_index name parent type ShortText table Terms name Events_parent_index flags WITH_POSITION
# tags type map tag "\"sharetary.tag\"" time time record ({ "_key" => record["url"].match(/repos\/([^\/]+\/[^\/]+)\/commits/)[1], "icon" => record["$github-activities-related-organization-logo"] }) type map tag "\"sharetary.tag\"" time time record ({ "_key" => record["payload"]["forkee"]["full_name"], "icon" => record["$github-activities-related-organization-logo"] }) type map tag "\"sharetary.tag\"" time time record ({ "_key" => record["repo"]["name"], "icon" => record["$github-activities-related-organization-logo"] }) 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 name Tags flags TABLE_HASH_KEY key_type ShortText
name icon type ShortText
# actor type map tag "\"sharetary.actor\"" time time record ({ "_key" => (record["actor"] || record["committer"])["login"], "uri" => "https://github.com/#{(record["actor"] || record["committer"])["login"]}/", "icon" => record["$github-activities-related-avatar"], "class" => "major" }) type map tag "\"sharetary.actor\"" time time record ({ "_key" => (record["actor"] || record["committer"])["login"], "uri" => "https://github.com/#{(record["actor"] || record["committer"])["login"]}/", "icon" => record["$github-activities-related-avatar"], "class" => "minor" }) 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 name Actors flags TABLE_HASH_KEY key_type ShortText
name uri type ShortText name icon type ShortText name class type ShortText