{"action":"created","comment":{"url":"https://api.github.com/repos/stripe/veneur/pulls/comments/85611204","pull_request_review_id":6320368,"id":85611204,"diff_hunk":"@@ -28,98 +28,132 @@ type DDMetric struct {\n \tInterval   int32         `json:\"interval,omitempty\"`\n }\n \n-type tsvField int\n+type Aggregate int\n \n const (\n-\t// the order in which these appear determines the\n-\t// order of the fields in the resultant TSV\n-\ttsvName tsvField = iota\n-\ttsvTags\n-\ttsvMetricType\n-\n-\t// The hostname attached to the metric\n-\ttsvHostname\n-\n-\t// The hostname of the server flushing the data\n-\ttsvVeneurHostname\n-\n-\ttsvDeviceName\n-\ttsvInterval\n-\n-\ttsvTimestamp\n-\ttsvValue\n-\n-\t// This is the _partition field\n-\t// required by the Redshift IncrementalLoader.\n-\t// For our purposes, the current date is a good partition.\n-\ttsvPartition\n+\tAggregateMin Aggregate = 1 << iota\n+\tAggregateMax\n+\tAggregateMedian\n+\tAggregateAverage\n+\tAggregateCount\n+\tAggregateSum\n )\n \n-var tsvSchema = [...]string{\n-\ttsvName:           \"tsvName\",\n-\ttsvTags:           \"tsvTags\",\n-\ttsvMetricType:     \"tsvMetricType\",\n-\ttsvHostname:       \"tsvHostname\",\n-\ttsvDeviceName:     \"tsvDeviceName\",\n-\ttsvInterval:       \"tsvInterval\",\n-\ttsvVeneurHostname: \"tsvVeneurHostname\",\n-\ttsvTimestamp:      \"tsvTimestamp\",\n-\ttsvValue:          \"tsvValue\",\n-\ttsvPartition:      \"tsvPartition\",\n+var AggregatesLookup = map[string]Aggregate{\n+\t\"min\":    AggregateMin,\n+\t\"max\":    AggregateMax,\n+\t\"median\": AggregateMedian,\n+\t\"avg\":    AggregateAverage,\n+\t\"count\":  AggregateCount,\n+\t\"sum\":    AggregateSum,\n }\n \n-// String returns the field name.\n-// eg tsvName.String() returns \"Name\"\n-func (f tsvField) String() string {\n-\treturn fmt.Sprintf(strings.Replace(tsvSchema[f], \"tsv\", \"\", 1))\n+type HistogramAggregates struct {\n+\tValue Aggregate\n+\tCount int\n }\n \n-// each key in tsvMapping is guaranteed to have a unique value\n-var tsvMapping = map[string]int{}\n-\n-func init() {\n-\tfor i, field := range tsvSchema {\n-\t\ttsvMapping[field] = i\n-\t}\n+var aggregates = [...]string{\n+\tAggregateMin:     \"min\",\n+\tAggregateMax:     \"max\",\n+\tAggregateMedian:  \"median\",\n+\tAggregateAverage: \"avg\",\n+\tAggregateCount:   \"count\",\n+\tAggregateSum:     \"sum\",\n }\n \n-// encodeCSV generates a newline-terminated CSV row that describes\n+// EncodeCSV generates a newline-terminated CSV row that describes\n // the data represented by the DDMetric.\n // The caller is responsible for setting w.Comma as the appropriate delimiter.\n // For performance, encodeCSV does not flush after every call; the caller is\n // expected to flush at the end of the operation cycle\n-func (d DDMetric) encodeCSV(w *csv.Writer, partitionDate *time.Time, hostname string) error {\n+func (d DDMetric) EncodeCSV(w *csv.Writer, partitionDate *time.Time, hostName string) error {","path":"samplers/samplers.go","position":96,"original_position":96,"commit_id":"a3348eb7add79c55cd2a4ac84918c0a4927027cd","original_commit_id":"a3348eb7add79c55cd2a4ac84918c0a4927027cd","user":{"login":"sjung-stripe","id":23090673,"avatar_url":"https://avatars.githubusercontent.com/u/23090673?v=3","gravatar_id":"","url":"https://api.github.com/users/sjung-stripe","html_url":"https://github.com/sjung-stripe","followers_url":"https://api.github.com/users/sjung-stripe/followers","following_url":"https://api.github.com/users/sjung-stripe/following{/other_user}","gists_url":"https://api.github.com/users/sjung-stripe/gists{/gist_id}","starred_url":"https://api.github.com/users/sjung-stripe/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sjung-stripe/subscriptions","organizations_url":"https://api.github.com/users/sjung-stripe/orgs","repos_url":"https://api.github.com/users/sjung-stripe/repos","events_url":"https://api.github.com/users/sjung-stripe/events{/privacy}","received_events_url":"https://api.github.com/users/sjung-stripe/received_events","type":"User","site_admin":false},"body":"did we agree that we would move this into s3 package? not saying we have to do it now but just making sure we remember to do it","created_at":"2016-10-28T21:12:16Z","updated_at":"2016-10-28T21:12:16Z","html_url":"https://github.com/stripe/veneur/pull/95#discussion_r85611204","pull_request_url":"https://api.github.com/repos/stripe/veneur/pulls/95","_links":{"self":{"href":"https://api.github.com/repos/stripe/veneur/pulls/comments/85611204"},"html":{"href":"https://github.com/stripe/veneur/pull/95#discussion_r85611204"},"pull_request":{"href":"https://api.github.com/repos/stripe/veneur/pulls/95"}}},"pull_request":{"url":"https://api.github.com/repos/stripe/veneur/pulls/95","id":90070042,"html_url":"https://github.com/stripe/veneur/pull/95","diff_url":"https://github.com/stripe/veneur/pull/95.diff","patch_url":"https://github.com/stripe/veneur/pull/95.patch","issue_url":"https://api.github.com/repos/stripe/veneur/issues/95","number":95,"state":"open","locked":false,"title":"Split S3 plugin into separate package","user":{"login":"ChimeraCoder","id":376414,"avatar_url":"https://avatars.githubusercontent.com/u/376414?v=3","gravatar_id":"","url":"https://api.github.com/users/ChimeraCoder","html_url":"https://github.com/ChimeraCoder","followers_url":"https://api.github.com/users/ChimeraCoder/followers","following_url":"https://api.github.com/users/ChimeraCoder/following{/other_user}","gists_url":"https://api.github.com/users/ChimeraCoder/gists{/gist_id}","starred_url":"https://api.github.com/users/ChimeraCoder/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ChimeraCoder/subscriptions","organizations_url":"https://api.github.com/users/ChimeraCoder/orgs","repos_url":"https://api.github.com/users/ChimeraCoder/repos","events_url":"https://api.github.com/users/ChimeraCoder/events{/privacy}","received_events_url":"https://api.github.com/users/ChimeraCoder/received_events","type":"User","site_admin":false},"body":"#### Summary\r\n\r\nMove the S3 plugin logic to a separate plugin. This involved a lot of refactoring to get the dependency graph back into a DAG.\r\n\r\n\r\nThere was one part where I duplicated code (the function that generates the CSV fixtures used in both `samplers_test.go` and `s3_test.go`). Refactoring this out would have required splitting the DDMetric type into its own package (to avoid a circular import), and it turns out that would be a pain. Not impossible, but annoying enough that I punted on it.\r\n\r\n\r\n#### Motivation\r\n\r\nAside from cleaner organization, this gives us better insight into the interfaces between our plugin(s) and the rest of veneur (and, as an additional benefit, the inter-interfaces within veneur). \r\n\r\n\r\n#### Test plan\r\n\r\nUpdated tests.\r\n\r\n#### Rollout/monitoring/revert plan\r\n\r\n\r\nr? @tummychow \r\n","created_at":"2016-10-19T18:59:57Z","updated_at":"2016-10-28T21:18:09Z","closed_at":null,"merged_at":null,"merge_commit_sha":"fb6a9fced0826a8441fccfd52966ac798fde48de","assignee":{"login":"tummychow","id":4285049,"avatar_url":"https://avatars.githubusercontent.com/u/4285049?v=3","gravatar_id":"","url":"https://api.github.com/users/tummychow","html_url":"https://github.com/tummychow","followers_url":"https://api.github.com/users/tummychow/followers","following_url":"https://api.github.com/users/tummychow/following{/other_user}","gists_url":"https://api.github.com/users/tummychow/gists{/gist_id}","starred_url":"https://api.github.com/users/tummychow/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tummychow/subscriptions","organizations_url":"https://api.github.com/users/tummychow/orgs","repos_url":"https://api.github.com/users/tummychow/repos","events_url":"https://api.github.com/users/tummychow/events{/privacy}","received_events_url":"https://api.github.com/users/tummychow/received_events","type":"User","site_admin":false},"assignees":[{"login":"tummychow","id":4285049,"avatar_url":"https://avatars.githubusercontent.com/u/4285049?v=3","gravatar_id":"","url":"https://api.github.com/users/tummychow","html_url":"https://github.com/tummychow","followers_url":"https://api.github.com/users/tummychow/followers","following_url":"https://api.github.com/users/tummychow/following{/other_user}","gists_url":"https://api.github.com/users/tummychow/gists{/gist_id}","starred_url":"https://api.github.com/users/tummychow/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tummychow/subscriptions","organizations_url":"https://api.github.com/users/tummychow/orgs","repos_url":"https://api.github.com/users/tummychow/repos","events_url":"https://api.github.com/users/tummychow/events{/privacy}","received_events_url":"https://api.github.com/users/tummychow/received_events","type":"User","site_admin":false},{"login":"sjung-stripe","id":23090673,"avatar_url":"https://avatars.githubusercontent.com/u/23090673?v=3","gravatar_id":"","url":"https://api.github.com/users/sjung-stripe","html_url":"https://github.com/sjung-stripe","followers_url":"https://api.github.com/users/sjung-stripe/followers","following_url":"https://api.github.com/users/sjung-stripe/following{/other_user}","gists_url":"https://api.github.com/users/sjung-stripe/gists{/gist_id}","starred_url":"https://api.github.com/users/sjung-stripe/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sjung-stripe/subscriptions","organizations_url":"https://api.github.com/users/sjung-stripe/orgs","repos_url":"https://api.github.com/users/sjung-stripe/repos","events_url":"https://api.github.com/users/sjung-stripe/events{/privacy}","received_events_url":"https://api.github.com/users/sjung-stripe/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/stripe/veneur/pulls/95/commits","review_comments_url":"https://api.github.com/repos/stripe/veneur/pulls/95/comments","review_comment_url":"https://api.github.com/repos/stripe/veneur/pulls/comments{/number}","comments_url":"https://api.github.com/repos/stripe/veneur/issues/95/comments","statuses_url":"https://api.github.com/repos/stripe/veneur/statuses/a3348eb7add79c55cd2a4ac84918c0a4927027cd","head":{"label":"stripe:aditya-s3-plugin","ref":"aditya-s3-plugin","sha":"a3348eb7add79c55cd2a4ac84918c0a4927027cd","user":{"login":"stripe","id":856813,"avatar_url":"https://avatars.githubusercontent.com/u/856813?v=3","gravatar_id":"","url":"https://api.github.com/users/stripe","html_url":"https://github.com/stripe","followers_url":"https://api.github.com/users/stripe/followers","following_url":"https://api.github.com/users/stripe/following{/other_user}","gists_url":"https://api.github.com/users/stripe/gists{/gist_id}","starred_url":"https://api.github.com/users/stripe/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stripe/subscriptions","organizations_url":"https://api.github.com/users/stripe/orgs","repos_url":"https://api.github.com/users/stripe/repos","events_url":"https://api.github.com/users/stripe/events{/privacy}","received_events_url":"https://api.github.com/users/stripe/received_events","type":"Organization","site_admin":false},"repo":{"id":55277533,"name":"veneur","full_name":"stripe/veneur","owner":{"login":"stripe","id":856813,"avatar_url":"https://avatars.githubusercontent.com/u/856813?v=3","gravatar_id":"","url":"https://api.github.com/users/stripe","html_url":"https://github.com/stripe","followers_url":"https://api.github.com/users/stripe/followers","following_url":"https://api.github.com/users/stripe/following{/other_user}","gists_url":"https://api.github.com/users/stripe/gists{/gist_id}","starred_url":"https://api.github.com/users/stripe/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stripe/subscriptions","organizations_url":"https://api.github.com/users/stripe/orgs","repos_url":"https://api.github.com/users/stripe/repos","events_url":"https://api.github.com/users/stripe/events{/privacy}","received_events_url":"https://api.github.com/users/stripe/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/stripe/veneur","description":"A DogStatsD server implementation with global aggregation capability.","fork":false,"url":"https://api.github.com/repos/stripe/veneur","forks_url":"https://api.github.com/repos/stripe/veneur/forks","keys_url":"https://api.github.com/repos/stripe/veneur/keys{/key_id}","collaborators_url":"https://api.github.com/repos/stripe/veneur/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/stripe/veneur/teams","hooks_url":"https://api.github.com/repos/stripe/veneur/hooks","issue_events_url":"https://api.github.com/repos/stripe/veneur/issues/events{/number}","events_url":"https://api.github.com/repos/stripe/veneur/events","assignees_url":"https://api.github.com/repos/stripe/veneur/assignees{/user}","branches_url":"https://api.github.com/repos/stripe/veneur/branches{/branch}","tags_url":"https://api.github.com/repos/stripe/veneur/tags","blobs_url":"https://api.github.com/repos/stripe/veneur/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/stripe/veneur/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/stripe/veneur/git/refs{/sha}","trees_url":"https://api.github.com/repos/stripe/veneur/git/trees{/sha}","statuses_url":"https://api.github.com/repos/stripe/veneur/statuses/{sha}","languages_url":"https://api.github.com/repos/stripe/veneur/languages","stargazers_url":"https://api.github.com/repos/stripe/veneur/stargazers","contributors_url":"https://api.github.com/repos/stripe/veneur/contributors","subscribers_url":"https://api.github.com/repos/stripe/veneur/subscribers","subscription_url":"https://api.github.com/repos/stripe/veneur/subscription","commits_url":"https://api.github.com/repos/stripe/veneur/commits{/sha}","git_commits_url":"https://api.github.com/repos/stripe/veneur/git/commits{/sha}","comments_url":"https://api.github.com/repos/stripe/veneur/comments{/number}","issue_comment_url":"https://api.github.com/repos/stripe/veneur/issues/comments{/number}","contents_url":"https://api.github.com/repos/stripe/veneur/contents/{+path}","compare_url":"https://api.github.com/repos/stripe/veneur/compare/{base}...{head}","merges_url":"https://api.github.com/repos/stripe/veneur/merges","archive_url":"https://api.github.com/repos/stripe/veneur/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/stripe/veneur/downloads","issues_url":"https://api.github.com/repos/stripe/veneur/issues{/number}","pulls_url":"https://api.github.com/repos/stripe/veneur/pulls{/number}","milestones_url":"https://api.github.com/repos/stripe/veneur/milestones{/number}","notifications_url":"https://api.github.com/repos/stripe/veneur/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/stripe/veneur/labels{/name}","releases_url":"https://api.github.com/repos/stripe/veneur/releases{/id}","deployments_url":"https://api.github.com/repos/stripe/veneur/deployments","created_at":"2016-04-02T04:24:34Z","updated_at":"2016-10-28T15:11:26Z","pushed_at":"2016-10-28T21:05:08Z","git_url":"git://github.com/stripe/veneur.git","ssh_url":"git@github.com:stripe/veneur.git","clone_url":"https://github.com/stripe/veneur.git","svn_url":"https://github.com/stripe/veneur","homepage":"","size":1872,"stargazers_count":155,"watchers_count":155,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4,"mirror_url":null,"open_issues_count":5,"forks":4,"open_issues":5,"watchers":155,"default_branch":"master"}},"base":{"label":"stripe:master","ref":"master","sha":"7162efdfd809aabcd2eb2e36a32de9e37eb6d3f0","user":{"login":"stripe","id":856813,"avatar_url":"https://avatars.githubusercontent.com/u/856813?v=3","gravatar_id":"","url":"https://api.github.com/users/stripe","html_url":"https://github.com/stripe","followers_url":"https://api.github.com/users/stripe/followers","following_url":"https://api.github.com/users/stripe/following{/other_user}","gists_url":"https://api.github.com/users/stripe/gists{/gist_id}","starred_url":"https://api.github.com/users/stripe/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stripe/subscriptions","organizations_url":"https://api.github.com/users/stripe/orgs","repos_url":"https://api.github.com/users/stripe/repos","events_url":"https://api.github.com/users/stripe/events{/privacy}","received_events_url":"https://api.github.com/users/stripe/received_events","type":"Organization","site_admin":false},"repo":{"id":55277533,"name":"veneur","full_name":"stripe/veneur","owner":{"login":"stripe","id":856813,"avatar_url":"https://avatars.githubusercontent.com/u/856813?v=3","gravatar_id":"","url":"https://api.github.com/users/stripe","html_url":"https://github.com/stripe","followers_url":"https://api.github.com/users/stripe/followers","following_url":"https://api.github.com/users/stripe/following{/other_user}","gists_url":"https://api.github.com/users/stripe/gists{/gist_id}","starred_url":"https://api.github.com/users/stripe/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stripe/subscriptions","organizations_url":"https://api.github.com/users/stripe/orgs","repos_url":"https://api.github.com/users/stripe/repos","events_url":"https://api.github.com/users/stripe/events{/privacy}","received_events_url":"https://api.github.com/users/stripe/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/stripe/veneur","description":"A DogStatsD server implementation with global aggregation capability.","fork":false,"url":"https://api.github.com/repos/stripe/veneur","forks_url":"https://api.github.com/repos/stripe/veneur/forks","keys_url":"https://api.github.com/repos/stripe/veneur/keys{/key_id}","collaborators_url":"https://api.github.com/repos/stripe/veneur/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/stripe/veneur/teams","hooks_url":"https://api.github.com/repos/stripe/veneur/hooks","issue_events_url":"https://api.github.com/repos/stripe/veneur/issues/events{/number}","events_url":"https://api.github.com/repos/stripe/veneur/events","assignees_url":"https://api.github.com/repos/stripe/veneur/assignees{/user}","branches_url":"https://api.github.com/repos/stripe/veneur/branches{/branch}","tags_url":"https://api.github.com/repos/stripe/veneur/tags","blobs_url":"https://api.github.com/repos/stripe/veneur/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/stripe/veneur/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/stripe/veneur/git/refs{/sha}","trees_url":"https://api.github.com/repos/stripe/veneur/git/trees{/sha}","statuses_url":"https://api.github.com/repos/stripe/veneur/statuses/{sha}","languages_url":"https://api.github.com/repos/stripe/veneur/languages","stargazers_url":"https://api.github.com/repos/stripe/veneur/stargazers","contributors_url":"https://api.github.com/repos/stripe/veneur/contributors","subscribers_url":"https://api.github.com/repos/stripe/veneur/subscribers","subscription_url":"https://api.github.com/repos/stripe/veneur/subscription","commits_url":"https://api.github.com/repos/stripe/veneur/commits{/sha}","git_commits_url":"https://api.github.com/repos/stripe/veneur/git/commits{/sha}","comments_url":"https://api.github.com/repos/stripe/veneur/comments{/number}","issue_comment_url":"https://api.github.com/repos/stripe/veneur/issues/comments{/number}","contents_url":"https://api.github.com/repos/stripe/veneur/contents/{+path}","compare_url":"https://api.github.com/repos/stripe/veneur/compare/{base}...{head}","merges_url":"https://api.github.com/repos/stripe/veneur/merges","archive_url":"https://api.github.com/repos/stripe/veneur/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/stripe/veneur/downloads","issues_url":"https://api.github.com/repos/stripe/veneur/issues{/number}","pulls_url":"https://api.github.com/repos/stripe/veneur/pulls{/number}","milestones_url":"https://api.github.com/repos/stripe/veneur/milestones{/number}","notifications_url":"https://api.github.com/repos/stripe/veneur/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/stripe/veneur/labels{/name}","releases_url":"https://api.github.com/repos/stripe/veneur/releases{/id}","deployments_url":"https://api.github.com/repos/stripe/veneur/deployments","created_at":"2016-04-02T04:24:34Z","updated_at":"2016-10-28T15:11:26Z","pushed_at":"2016-10-28T21:05:08Z","git_url":"git://github.com/stripe/veneur.git","ssh_url":"git@github.com:stripe/veneur.git","clone_url":"https://github.com/stripe/veneur.git","svn_url":"https://github.com/stripe/veneur","homepage":"","size":1872,"stargazers_count":155,"watchers_count":155,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4,"mirror_url":null,"open_issues_count":5,"forks":4,"open_issues":5,"watchers":155,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/stripe/veneur/pulls/95"},"html":{"href":"https://github.com/stripe/veneur/pull/95"},"issue":{"href":"https://api.github.com/repos/stripe/veneur/issues/95"},"comments":{"href":"https://api.github.com/repos/stripe/veneur/issues/95/comments"},"review_comments":{"href":"https://api.github.com/repos/stripe/veneur/pulls/95/comments"},"review_comment":{"href":"https://api.github.com/repos/stripe/veneur/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/stripe/veneur/pulls/95/commits"},"statuses":{"href":"https://api.github.com/repos/stripe/veneur/statuses/a3348eb7add79c55cd2a4ac84918c0a4927027cd"}}}}
{"actor":{"display_login":"sjung-stripe"}}