{"action":"created","comment":{"url":"https://api.github.com/repos/getlantern/lantern/pulls/comments/62477587","id":62477587,"diff_hunk":"@@ -0,0 +1,540 @@\n+/*\n+Package errlog defines error types used across Lantern project and implements\n+functions to manipulate them.\n+\n+  var elog = errlog.ErrorLoggerFor(\"package-name\")\n+  //...\n+  if n, err := Foo(); err != nil {\n+    elog.Log(err)\n+  }\n+\n+Log() method will try as much as possible to extract details from the error\n+passed in, if it's errors defined in Go standard library. For application\n+defined error type, at least the Go type name and what yourErr.Error() returns\n+will be recorded.\n+\n+Extra parameters can be passed like this in any order.\n+  elog.Log(err, errlog.WithOp(\"proxy\"), errlog.WithUserAgent(\"Mozilla/5.0...\"))\n+\n+Or to attach arbitrary data with the error.\n+  elog.Log(err, errlog.WithField(\"foo\": \"bar\"))\n+\n+Guildlines to report error:\n+\n+1. Report at the end of error propagation chain, that is, before the code\n+resumes from the error or makes a decision based on it.\n+\n+2. Report when more relevant knowledge is available.\n+\n+The purpose is to avoid reporting repetitively, and prevent lower level of code\n+from depending on this package.\n+*/\n+package errlog\n+\n+import (\n+\t\"bufio\"\n+\t\"bytes\"\n+\t\"crypto/tls\"\n+\t\"crypto/x509\"\n+\t\"encoding/hex\"\n+\t\"encoding/json\"\n+\t\"fmt\"\n+\t\"io\"\n+\t\"net\"\n+\t\"net/http\"\n+\t\"net/textproto\"\n+\t\"net/url\"\n+\t\"os\"\n+\t\"os/exec\"\n+\t\"reflect\"\n+\t\"runtime\"\n+\t\"strconv\"\n+\t\"syscall\"\n+\t\"time\"\n+\n+\t\"github.com/getlantern/golog\"\n+\t\"github.com/getlantern/jibber_jabber\"\n+\t\"github.com/getlantern/osversion\"\n+)\n+\n+type systemInfo struct {\n+\tOSType    string `json:\"osType\"`\n+\tOSVersion string `json:\"osVersion\"`\n+\tOSArch    string `json:\"osArch\"`\n+}\n+\n+func (si *systemInfo) String() string {\n+\tvar buf bytes.Buffer\n+\tif si.OSType != \"\" {\n+\t\t_, _ = buf.WriteString(\" OSType=\" + si.OSType)\n+\t}\n+\tif si.OSVersion != \"\" {\n+\t\t_, _ = buf.WriteString(\" OSVersion=\\\"\" + si.OSVersion + \"\\\"\")\n+\t}\n+\tif si.OSArch != \"\" {\n+\t\t_, _ = buf.WriteString(\" OSArch=\" + si.OSArch)\n+\t}\n+\treturn buf.String()\n+}\n+\n+type UserLocale struct {\n+\tTimeZone string `json:\"timeZone,omitempty\"`\n+\tLanguage string `json:\"language,omitempty\"`\n+\tCountry  string `json:\"country,omitempty\"`\n+}\n+\n+func (si *UserLocale) String() string {\n+\tvar buf bytes.Buffer\n+\tif si.TimeZone != \"\" {\n+\t\t_, _ = buf.WriteString(\" TimeZone=\" + si.TimeZone)\n+\t}\n+\tif si.Language != \"\" {\n+\t\t_, _ = buf.WriteString(\" Language=\" + si.Language)\n+\t}\n+\tif si.Country != \"\" {\n+\t\t_, _ = buf.WriteString(\" Country=\" + si.Country)\n+\t}\n+\treturn buf.String()\n+}\n+\n+// ProxyType is the type of various proxy channel\n+type ProxyType string\n+\n+const (\n+\t// direct access, no proxying at all\n+\tNoProxy ProxyType = \"no\"\n+\t// access through Lantern hosted chained server\n+\tChainedProxy ProxyType = \"chained\"\n+\t// access through domain fronting\n+\tFrontedProxy ProxyType = \"fronted\"\n+\t// access through direct domain fronting\n+\tDirectFrontedProxy ProxyType = \"DDF\"\n+)\n+\n+// ProxyingInfo encapsulates fields to describe an access through a proxy channel.\n+type ProxyingInfo struct {\n+\tProxyType  ProxyType `json:\"proxyType,omitempty\"`\n+\tLocalAddr  string    `json:\"localAddr,omitempty\"`\n+\tProxyAddr  string    `json:\"proxyAddr,omitempty\"`\n+\tProxyDC    string    `json:\"proxyDataCenter,omitempty\"`\n+\tOriginSite string    `json:\"originSite,omitempty\"`\n+\tScheme     string    `json:\"scheme,omitempty\"`\n+}\n+\n+func (pi *ProxyingInfo) String() string {\n+\tvar buf bytes.Buffer\n+\tif pi.ProxyType != \"\" {\n+\t\t_, _ = buf.WriteString(\" ProxyType=\" + string(pi.ProxyType))\n+\t}\n+\tif pi.LocalAddr != \"\" {\n+\t\t_, _ = buf.WriteString(\" LocalAddr=\" + pi.LocalAddr)\n+\t}\n+\tif pi.ProxyAddr != \"\" {\n+\t\t_, _ = buf.WriteString(\" ProxyAddr=\" + pi.ProxyAddr)\n+\t}\n+\tif pi.ProxyDC != \"\" {\n+\t\t_, _ = buf.WriteString(\" ProxyDC=\" + pi.ProxyDC)\n+\t}\n+\tif pi.OriginSite != \"\" {\n+\t\t_, _ = buf.WriteString(\" OriginSite=\" + pi.OriginSite)\n+\t}\n+\tif pi.Scheme != \"\" {\n+\t\t_, _ = buf.WriteString(\" Scheme=\" + pi.Scheme)\n+\t}\n+\treturn buf.String()\n+}\n+\n+// UserAgentInfo encapsulates traits of the browsers or 3rd party applications\n+// directing traffic through Lantern.\n+type UserAgentInfo struct {\n+\tUserAgent string `json:\"userAgent,omitempty\"`\n+}\n+\n+func (ul *UserAgentInfo) String() string {\n+\treturn fmt.Sprintf(\"UserAgent=%s\", ul.UserAgent)\n+}\n+\n+// Error wraps system and application errors in unified structure\n+type Error struct {","path":"src/github.com/getlantern/errlog/errlog.go","position":158,"original_position":158,"commit_id":"e15c8e3e8b52236704fea5d3026114fd07567ed1","original_commit_id":"e15c8e3e8b52236704fea5d3026114fd07567ed1","user":{"login":"fffw","id":10410437,"avatar_url":"https://avatars.githubusercontent.com/u/10410437?v=3","gravatar_id":"","url":"https://api.github.com/users/fffw","html_url":"https://github.com/fffw","followers_url":"https://api.github.com/users/fffw/followers","following_url":"https://api.github.com/users/fffw/following{/other_user}","gists_url":"https://api.github.com/users/fffw/gists{/gist_id}","starred_url":"https://api.github.com/users/fffw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fffw/subscriptions","organizations_url":"https://api.github.com/users/fffw/orgs","repos_url":"https://api.github.com/users/fffw/repos","events_url":"https://api.github.com/users/fffw/events{/privacy}","received_events_url":"https://api.github.com/users/fffw/received_events","type":"User","site_admin":false},"body":"The problem is that we can't predefine all possible codes. It's also tedious for the caller to find the correct error codes. For monitoring purpose, most operations are not to exactly match a few error codes, but list the top N errors, show the distribution, or send alert if the count exceeds some criteria. For troubleshooting, we have user id, device id, request id, ip address, etc to acurately filter the dataset.\r\n\r\nChanged field value does little harm as they are same in a version.","created_at":"2016-05-09T10:22:16Z","updated_at":"2016-05-09T10:22:16Z","html_url":"https://github.com/getlantern/lantern/pull/4237#discussion_r62477587","pull_request_url":"https://api.github.com/repos/getlantern/lantern/pulls/4237","_links":{"self":{"href":"https://api.github.com/repos/getlantern/lantern/pulls/comments/62477587"},"html":{"href":"https://github.com/getlantern/lantern/pull/4237#discussion_r62477587"},"pull_request":{"href":"https://api.github.com/repos/getlantern/lantern/pulls/4237"}}},"pull_request":{"url":"https://api.github.com/repos/getlantern/lantern/pulls/4237","id":69262409,"html_url":"https://github.com/getlantern/lantern/pull/4237","diff_url":"https://github.com/getlantern/lantern/pull/4237.diff","patch_url":"https://github.com/getlantern/lantern/pull/4237.patch","issue_url":"https://api.github.com/repos/getlantern/lantern/issues/4237","number":4237,"state":"open","locked":false,"title":"[WIP] structural error reporting","user":{"login":"fffw","id":10410437,"avatar_url":"https://avatars.githubusercontent.com/u/10410437?v=3","gravatar_id":"","url":"https://api.github.com/users/fffw","html_url":"https://github.com/fffw","followers_url":"https://api.github.com/users/fffw/followers","following_url":"https://api.github.com/users/fffw/following{/other_user}","gists_url":"https://api.github.com/users/fffw/gists{/gist_id}","starred_url":"https://api.github.com/users/fffw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fffw/subscriptions","organizations_url":"https://api.github.com/users/fffw/orgs","repos_url":"https://api.github.com/users/fffw/repos","events_url":"https://api.github.com/users/fffw/events{/privacy}","received_events_url":"https://api.github.com/users/fffw/received_events","type":"User","site_admin":false},"body":"","created_at":"2016-05-08T06:59:32Z","updated_at":"2016-05-09T10:22:16Z","closed_at":null,"merged_at":null,"merge_commit_sha":"2862f40a26ed23673fbaef24fbbad5132c4fc9c0","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/getlantern/lantern/pulls/4237/commits","review_comments_url":"https://api.github.com/repos/getlantern/lantern/pulls/4237/comments","review_comment_url":"https://api.github.com/repos/getlantern/lantern/pulls/comments{/number}","comments_url":"https://api.github.com/repos/getlantern/lantern/issues/4237/comments","statuses_url":"https://api.github.com/repos/getlantern/lantern/statuses/e15c8e3e8b52236704fea5d3026114fd07567ed1","head":{"label":"getlantern:issue4172","ref":"issue4172","sha":"e15c8e3e8b52236704fea5d3026114fd07567ed1","user":{"login":"getlantern","id":624178,"avatar_url":"https://avatars.githubusercontent.com/u/624178?v=3","gravatar_id":"","url":"https://api.github.com/users/getlantern","html_url":"https://github.com/getlantern","followers_url":"https://api.github.com/users/getlantern/followers","following_url":"https://api.github.com/users/getlantern/following{/other_user}","gists_url":"https://api.github.com/users/getlantern/gists{/gist_id}","starred_url":"https://api.github.com/users/getlantern/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/getlantern/subscriptions","organizations_url":"https://api.github.com/users/getlantern/orgs","repos_url":"https://api.github.com/users/getlantern/repos","events_url":"https://api.github.com/users/getlantern/events{/privacy}","received_events_url":"https://api.github.com/users/getlantern/received_events","type":"Organization","site_admin":false},"repo":{"id":1380117,"name":"lantern","full_name":"getlantern/lantern","owner":{"login":"getlantern","id":624178,"avatar_url":"https://avatars.githubusercontent.com/u/624178?v=3","gravatar_id":"","url":"https://api.github.com/users/getlantern","html_url":"https://github.com/getlantern","followers_url":"https://api.github.com/users/getlantern/followers","following_url":"https://api.github.com/users/getlantern/following{/other_user}","gists_url":"https://api.github.com/users/getlantern/gists{/gist_id}","starred_url":"https://api.github.com/users/getlantern/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/getlantern/subscriptions","organizations_url":"https://api.github.com/users/getlantern/orgs","repos_url":"https://api.github.com/users/getlantern/repos","events_url":"https://api.github.com/users/getlantern/events{/privacy}","received_events_url":"https://api.github.com/users/getlantern/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/getlantern/lantern","description":":zap: Open Internet for everyone. Lantern is a free desktop application that delivers fast, reliable and secure access to the open Internet for users in censored regions. It uses a variety of techniques to stay unblocked, including P2P and domain fronting. Lantern relies on users in uncensored regions acting as access points to the open Internet.","fork":false,"url":"https://api.github.com/repos/getlantern/lantern","forks_url":"https://api.github.com/repos/getlantern/lantern/forks","keys_url":"https://api.github.com/repos/getlantern/lantern/keys{/key_id}","collaborators_url":"https://api.github.com/repos/getlantern/lantern/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/getlantern/lantern/teams","hooks_url":"https://api.github.com/repos/getlantern/lantern/hooks","issue_events_url":"https://api.github.com/repos/getlantern/lantern/issues/events{/number}","events_url":"https://api.github.com/repos/getlantern/lantern/events","assignees_url":"https://api.github.com/repos/getlantern/lantern/assignees{/user}","branches_url":"https://api.github.com/repos/getlantern/lantern/branches{/branch}","tags_url":"https://api.github.com/repos/getlantern/lantern/tags","blobs_url":"https://api.github.com/repos/getlantern/lantern/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/getlantern/lantern/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/getlantern/lantern/git/refs{/sha}","trees_url":"https://api.github.com/repos/getlantern/lantern/git/trees{/sha}","statuses_url":"https://api.github.com/repos/getlantern/lantern/statuses/{sha}","languages_url":"https://api.github.com/repos/getlantern/lantern/languages","stargazers_url":"https://api.github.com/repos/getlantern/lantern/stargazers","contributors_url":"https://api.github.com/repos/getlantern/lantern/contributors","subscribers_url":"https://api.github.com/repos/getlantern/lantern/subscribers","subscription_url":"https://api.github.com/repos/getlantern/lantern/subscription","commits_url":"https://api.github.com/repos/getlantern/lantern/commits{/sha}","git_commits_url":"https://api.github.com/repos/getlantern/lantern/git/commits{/sha}","comments_url":"https://api.github.com/repos/getlantern/lantern/comments{/number}","issue_comment_url":"https://api.github.com/repos/getlantern/lantern/issues/comments{/number}","contents_url":"https://api.github.com/repos/getlantern/lantern/contents/{+path}","compare_url":"https://api.github.com/repos/getlantern/lantern/compare/{base}...{head}","merges_url":"https://api.github.com/repos/getlantern/lantern/merges","archive_url":"https://api.github.com/repos/getlantern/lantern/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/getlantern/lantern/downloads","issues_url":"https://api.github.com/repos/getlantern/lantern/issues{/number}","pulls_url":"https://api.github.com/repos/getlantern/lantern/pulls{/number}","milestones_url":"https://api.github.com/repos/getlantern/lantern/milestones{/number}","notifications_url":"https://api.github.com/repos/getlantern/lantern/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/getlantern/lantern/labels{/name}","releases_url":"https://api.github.com/repos/getlantern/lantern/releases{/id}","deployments_url":"https://api.github.com/repos/getlantern/lantern/deployments","created_at":"2011-02-17T22:12:29Z","updated_at":"2016-05-09T10:06:35Z","pushed_at":"2016-05-09T02:51:21Z","git_url":"git://github.com/getlantern/lantern.git","ssh_url":"git@github.com:getlantern/lantern.git","clone_url":"https://github.com/getlantern/lantern.git","svn_url":"https://github.com/getlantern/lantern","homepage":"https://getlantern.org","size":1224118,"stargazers_count":14645,"watchers_count":14645,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3782,"mirror_url":null,"open_issues_count":385,"forks":3782,"open_issues":385,"watchers":14645,"default_branch":"devel"}},"base":{"label":"getlantern:devel","ref":"devel","sha":"4020b427218dc87b6efcebb754fd33c8ef18217f","user":{"login":"getlantern","id":624178,"avatar_url":"https://avatars.githubusercontent.com/u/624178?v=3","gravatar_id":"","url":"https://api.github.com/users/getlantern","html_url":"https://github.com/getlantern","followers_url":"https://api.github.com/users/getlantern/followers","following_url":"https://api.github.com/users/getlantern/following{/other_user}","gists_url":"https://api.github.com/users/getlantern/gists{/gist_id}","starred_url":"https://api.github.com/users/getlantern/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/getlantern/subscriptions","organizations_url":"https://api.github.com/users/getlantern/orgs","repos_url":"https://api.github.com/users/getlantern/repos","events_url":"https://api.github.com/users/getlantern/events{/privacy}","received_events_url":"https://api.github.com/users/getlantern/received_events","type":"Organization","site_admin":false},"repo":{"id":1380117,"name":"lantern","full_name":"getlantern/lantern","owner":{"login":"getlantern","id":624178,"avatar_url":"https://avatars.githubusercontent.com/u/624178?v=3","gravatar_id":"","url":"https://api.github.com/users/getlantern","html_url":"https://github.com/getlantern","followers_url":"https://api.github.com/users/getlantern/followers","following_url":"https://api.github.com/users/getlantern/following{/other_user}","gists_url":"https://api.github.com/users/getlantern/gists{/gist_id}","starred_url":"https://api.github.com/users/getlantern/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/getlantern/subscriptions","organizations_url":"https://api.github.com/users/getlantern/orgs","repos_url":"https://api.github.com/users/getlantern/repos","events_url":"https://api.github.com/users/getlantern/events{/privacy}","received_events_url":"https://api.github.com/users/getlantern/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/getlantern/lantern","description":":zap: Open Internet for everyone. Lantern is a free desktop application that delivers fast, reliable and secure access to the open Internet for users in censored regions. It uses a variety of techniques to stay unblocked, including P2P and domain fronting. Lantern relies on users in uncensored regions acting as access points to the open Internet.","fork":false,"url":"https://api.github.com/repos/getlantern/lantern","forks_url":"https://api.github.com/repos/getlantern/lantern/forks","keys_url":"https://api.github.com/repos/getlantern/lantern/keys{/key_id}","collaborators_url":"https://api.github.com/repos/getlantern/lantern/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/getlantern/lantern/teams","hooks_url":"https://api.github.com/repos/getlantern/lantern/hooks","issue_events_url":"https://api.github.com/repos/getlantern/lantern/issues/events{/number}","events_url":"https://api.github.com/repos/getlantern/lantern/events","assignees_url":"https://api.github.com/repos/getlantern/lantern/assignees{/user}","branches_url":"https://api.github.com/repos/getlantern/lantern/branches{/branch}","tags_url":"https://api.github.com/repos/getlantern/lantern/tags","blobs_url":"https://api.github.com/repos/getlantern/lantern/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/getlantern/lantern/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/getlantern/lantern/git/refs{/sha}","trees_url":"https://api.github.com/repos/getlantern/lantern/git/trees{/sha}","statuses_url":"https://api.github.com/repos/getlantern/lantern/statuses/{sha}","languages_url":"https://api.github.com/repos/getlantern/lantern/languages","stargazers_url":"https://api.github.com/repos/getlantern/lantern/stargazers","contributors_url":"https://api.github.com/repos/getlantern/lantern/contributors","subscribers_url":"https://api.github.com/repos/getlantern/lantern/subscribers","subscription_url":"https://api.github.com/repos/getlantern/lantern/subscription","commits_url":"https://api.github.com/repos/getlantern/lantern/commits{/sha}","git_commits_url":"https://api.github.com/repos/getlantern/lantern/git/commits{/sha}","comments_url":"https://api.github.com/repos/getlantern/lantern/comments{/number}","issue_comment_url":"https://api.github.com/repos/getlantern/lantern/issues/comments{/number}","contents_url":"https://api.github.com/repos/getlantern/lantern/contents/{+path}","compare_url":"https://api.github.com/repos/getlantern/lantern/compare/{base}...{head}","merges_url":"https://api.github.com/repos/getlantern/lantern/merges","archive_url":"https://api.github.com/repos/getlantern/lantern/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/getlantern/lantern/downloads","issues_url":"https://api.github.com/repos/getlantern/lantern/issues{/number}","pulls_url":"https://api.github.com/repos/getlantern/lantern/pulls{/number}","milestones_url":"https://api.github.com/repos/getlantern/lantern/milestones{/number}","notifications_url":"https://api.github.com/repos/getlantern/lantern/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/getlantern/lantern/labels{/name}","releases_url":"https://api.github.com/repos/getlantern/lantern/releases{/id}","deployments_url":"https://api.github.com/repos/getlantern/lantern/deployments","created_at":"2011-02-17T22:12:29Z","updated_at":"2016-05-09T10:06:35Z","pushed_at":"2016-05-09T02:51:21Z","git_url":"git://github.com/getlantern/lantern.git","ssh_url":"git@github.com:getlantern/lantern.git","clone_url":"https://github.com/getlantern/lantern.git","svn_url":"https://github.com/getlantern/lantern","homepage":"https://getlantern.org","size":1224118,"stargazers_count":14645,"watchers_count":14645,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3782,"mirror_url":null,"open_issues_count":385,"forks":3782,"open_issues":385,"watchers":14645,"default_branch":"devel"}},"_links":{"self":{"href":"https://api.github.com/repos/getlantern/lantern/pulls/4237"},"html":{"href":"https://github.com/getlantern/lantern/pull/4237"},"issue":{"href":"https://api.github.com/repos/getlantern/lantern/issues/4237"},"comments":{"href":"https://api.github.com/repos/getlantern/lantern/issues/4237/comments"},"review_comments":{"href":"https://api.github.com/repos/getlantern/lantern/pulls/4237/comments"},"review_comment":{"href":"https://api.github.com/repos/getlantern/lantern/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/getlantern/lantern/pulls/4237/commits"},"statuses":{"href":"https://api.github.com/repos/getlantern/lantern/statuses/e15c8e3e8b52236704fea5d3026114fd07567ed1"}}}}