You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

elk_pagedata.go 14 kB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. package repository
  2. import (
  3. "bytes"
  4. "encoding/base64"
  5. "encoding/json"
  6. "fmt"
  7. "io/ioutil"
  8. "net/http"
  9. "code.gitea.io/gitea/modules/log"
  10. "code.gitea.io/gitea/modules/setting"
  11. )
  12. //输入elk的json结构begin
  13. type InputInfo struct {
  14. Batch []Batch `json:"batch"`
  15. }
  16. type Fields struct {
  17. Field string `json:"field"`
  18. Format string `json:"format"`
  19. }
  20. type MatchPhrase struct {
  21. Message string `json:"message,omitempty"`
  22. TagName string `json:"tagName.keyword,omitempty"`
  23. }
  24. type Should struct {
  25. MatchPhrase MatchPhrase `json:"match_phrase"`
  26. }
  27. type Bool struct {
  28. Should []Should `json:"should"`
  29. MinimumShouldMatch int `json:"minimum_should_match"`
  30. }
  31. type Timestamptest struct {
  32. // Gte time.Time `json:"gte"`
  33. Gte string `json:"gte"`
  34. Lte string `json:"lte"`
  35. Format string `json:"format"`
  36. }
  37. type Range struct {
  38. Timestamptest Timestamptest `json:"@timestamptest"`
  39. }
  40. type FilterMatchPhrase struct {
  41. UserName string `json:"userName.keyword,omitempty"`
  42. ProjectName string `json:"projectName.keyword,omitempty"`
  43. TagName string `json:"tagName.keyword,omitempty"`
  44. }
  45. type Filter struct {
  46. Bool *Bool `json:"bool,omitempty"`
  47. Range *Range `json:"range,omitempty"`
  48. FilterMatchPhrase *FilterMatchPhrase `json:"match_phrase,omitempty"`
  49. }
  50. type MustNotMatchPhrase struct {
  51. ProjectName string `json:"projectName"`
  52. }
  53. type MustNot struct {
  54. MustNotMatchPhrase MustNotMatchPhrase `json:"match_phrase"`
  55. }
  56. type BoolIn struct {
  57. Filter []Filter `json:"filter"`
  58. MustNot []MustNot `json:"must_not"`
  59. }
  60. type Query struct {
  61. BoolIn BoolIn `json:"bool"`
  62. }
  63. type Body struct {
  64. Size int `json:"size"`
  65. Fields []Fields `json:"fields"`
  66. Query Query `json:"query"`
  67. }
  68. type Params struct {
  69. Index string `json:"index"`
  70. Body Body `json:"body"`
  71. }
  72. type Request struct {
  73. Params Params `json:"params"`
  74. }
  75. type Batch struct {
  76. Request Request `json:"request"`
  77. }
  78. //输入elk的json结构end
  79. //elk输出的json结构begin
  80. type Hits struct {
  81. Total int `json:"total"`
  82. }
  83. type RawResponse struct {
  84. Hits Hits `json:"hits"`
  85. }
  86. type Result struct {
  87. RawResponse RawResponse `json:"rawResponse"`
  88. Loaded int `json:"loaded"`
  89. }
  90. type ResultInfo struct {
  91. Id int `json:"id"`
  92. Result Result `json:"result"`
  93. }
  94. //elk输出的json结构end
  95. //处理返回的elk数据,只保留totalView,即访问量;loaded是分片载入次数,用来判断返回的数据是否准确
  96. func GetResultFromElk(resultInfo ResultInfo, jsonStr []byte) (loaded int, totalView int, err error) {
  97. ElkBase64Init := setting.ElkUser + ":" + setting.ElkPassword
  98. ElkBase64 := base64.StdEncoding.EncodeToString([]byte(ElkBase64Init))
  99. BasicElkBase64 := "Basic" + " " + ElkBase64
  100. url := setting.ElkUrl
  101. req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
  102. req.Header.Set("Content-Type", "application/json")
  103. req.Header.Set("kbn-version", "7.13.2")
  104. req.Header.Set("Authorization", BasicElkBase64)
  105. client := &http.Client{}
  106. resp, err := client.Do(req)
  107. if err != nil {
  108. // panic(err)
  109. return 0, 0, err
  110. }
  111. defer resp.Body.Close()
  112. if resp.StatusCode != 200 {
  113. log.Error("ConnectToElk failed:%s", resp.Status)
  114. return 0, 0, fmt.Errorf("ConnectToElk failed:%s", resp.Status)
  115. }
  116. body, err := ioutil.ReadAll(resp.Body)
  117. if err != nil {
  118. return 0, 0, err
  119. }
  120. err = json.Unmarshal([]byte(string(body)), &resultInfo)
  121. if err != nil {
  122. log.Error("Get resultJson failed", err)
  123. return 0, 0, err
  124. }
  125. return resultInfo.Result.Loaded, resultInfo.Result.RawResponse.Hits.Total, err
  126. }
  127. //初始化传给elk的数据结构,给定用户名和项目名,查询的起止时间,返回初始化后的结构
  128. func ProjectViewInit(User string, Project string, Gte string, Lte string) (projectViewInit InputInfo) {
  129. var inputStruct InputInfo
  130. inputStruct.Batch = make([]Batch, 1)
  131. inputStruct.Batch[0].Request.Params.Index = setting.Index
  132. inputStruct.Batch[0].Request.Params.Body.Size = 0
  133. inputStruct.Batch[0].Request.Params.Body.Fields = make([]Fields, 1)
  134. inputStruct.Batch[0].Request.Params.Body.Fields[0].Field = setting.TimeField
  135. inputStruct.Batch[0].Request.Params.Body.Fields[0].Format = setting.ElkTimeFormat
  136. inputStruct.Batch[0].Request.Params.Body.Query.BoolIn.Filter = make([]Filter, 4)
  137. //限定查询时间
  138. var timeRange Range
  139. timeRange.Timestamptest.Gte = Gte
  140. timeRange.Timestamptest.Lte = Lte
  141. timeRange.Timestamptest.Format = "strict_date_optional_time"
  142. inputStruct.Batch[0].Request.Params.Body.Query.BoolIn.Filter[0].Range = &timeRange
  143. //限定用户
  144. var userName FilterMatchPhrase
  145. userName.UserName = User
  146. inputStruct.Batch[0].Request.Params.Body.Query.BoolIn.Filter[1].FilterMatchPhrase = &userName
  147. //限定项目
  148. var projectName FilterMatchPhrase
  149. projectName.ProjectName = Project
  150. inputStruct.Batch[0].Request.Params.Body.Query.BoolIn.Filter[2].FilterMatchPhrase = &projectName
  151. //限定页面
  152. var bool Bool
  153. bool.Should = make([]Should, 14)
  154. bool.Should[0].MatchPhrase.TagName = "%{[request][3]}"
  155. bool.Should[1].MatchPhrase.TagName = "datasets?type=0"
  156. bool.Should[2].MatchPhrase.TagName = "datasets?type=1"
  157. bool.Should[3].MatchPhrase.TagName = "issues"
  158. bool.Should[4].MatchPhrase.TagName = "labels"
  159. bool.Should[5].MatchPhrase.TagName = "pulls"
  160. bool.Should[6].MatchPhrase.TagName = "wiki"
  161. bool.Should[7].MatchPhrase.TagName = "activity"
  162. bool.Should[8].MatchPhrase.TagName = "cloudbrain"
  163. bool.Should[9].MatchPhrase.TagName = "modelarts"
  164. bool.Should[10].MatchPhrase.TagName = "blockchain"
  165. bool.Should[11].MatchPhrase.TagName = "watchers"
  166. bool.Should[12].MatchPhrase.TagName = "stars"
  167. bool.Should[13].MatchPhrase.TagName = "forks"
  168. inputStruct.Batch[0].Request.Params.Body.Query.BoolIn.Filter[3].Bool = &bool
  169. return inputStruct
  170. }
  171. //初始化传给elk的数据结构,给定查询信息和非项目名,查询的起止时间,返回初始化后的结构
  172. func AllProjectViewInit(MessageInfo string, NotProject string, Gte string, Lte string) (allProjectViewInit InputInfo) {
  173. var inputStruct InputInfo
  174. inputStruct.Batch = make([]Batch, 1)
  175. inputStruct.Batch[0].Request.Params.Index = setting.Index
  176. inputStruct.Batch[0].Request.Params.Body.Size = 0
  177. inputStruct.Batch[0].Request.Params.Body.Fields = make([]Fields, 1)
  178. inputStruct.Batch[0].Request.Params.Body.Fields[0].Field = setting.TimeField
  179. inputStruct.Batch[0].Request.Params.Body.Fields[0].Format = setting.ElkTimeFormat
  180. inputStruct.Batch[0].Request.Params.Body.Query.BoolIn.Filter = make([]Filter, 2)
  181. //限定message
  182. var bool Bool
  183. bool.Should = make([]Should, 1)
  184. bool.Should[0].MatchPhrase.Message = MessageInfo
  185. bool.MinimumShouldMatch = 1
  186. inputStruct.Batch[0].Request.Params.Body.Query.BoolIn.Filter[0].Bool = &bool
  187. //限定查询时间
  188. var timeRange Range
  189. timeRange.Timestamptest.Gte = Gte
  190. timeRange.Timestamptest.Lte = Lte
  191. inputStruct.Batch[0].Request.Params.Body.Query.BoolIn.Filter[1].Range = &timeRange
  192. //限定非项目
  193. // var boolIn BoolIn
  194. inputStruct.Batch[0].Request.Params.Body.Query.BoolIn.MustNot = make([]MustNot, 1)
  195. inputStruct.Batch[0].Request.Params.Body.Query.BoolIn.MustNot[0].MustNotMatchPhrase.ProjectName = NotProject
  196. return inputStruct
  197. }
  198. //初始化传给elk的数据结构,给定查询信息和tagName,查询的起止时间,返回初始化后的结构
  199. func TagNameInit(MessageInfo string, Tagname string, Gte string, Lte string) (projectViewInit InputInfo) {
  200. var inputStruct InputInfo
  201. inputStruct.Batch = make([]Batch, 1)
  202. inputStruct.Batch[0].Request.Params.Index = setting.Index
  203. inputStruct.Batch[0].Request.Params.Body.Size = 0
  204. inputStruct.Batch[0].Request.Params.Body.Fields = make([]Fields, 1)
  205. inputStruct.Batch[0].Request.Params.Body.Fields[0].Field = setting.TimeField
  206. inputStruct.Batch[0].Request.Params.Body.Fields[0].Format = setting.ElkTimeFormat
  207. inputStruct.Batch[0].Request.Params.Body.Query.BoolIn.Filter = make([]Filter, 3)
  208. //限定message
  209. var bool Bool
  210. bool.Should = make([]Should, 1)
  211. bool.Should[0].MatchPhrase.Message = MessageInfo
  212. bool.MinimumShouldMatch = 1
  213. inputStruct.Batch[0].Request.Params.Body.Query.BoolIn.Filter[0].Bool = &bool
  214. //限定tagName
  215. var tagName FilterMatchPhrase
  216. tagName.TagName = Tagname
  217. inputStruct.Batch[0].Request.Params.Body.Query.BoolIn.Filter[1].FilterMatchPhrase = &tagName
  218. //限定查询时间
  219. var timeRange Range
  220. timeRange.Timestamptest.Gte = Gte
  221. timeRange.Timestamptest.Lte = Lte
  222. inputStruct.Batch[0].Request.Params.Body.Query.BoolIn.Filter[2].Range = &timeRange
  223. return inputStruct
  224. }
  225. //向elk发送请求,将获取的结果只保留访问量,输入是初始化后的数据结构,返回访问量
  226. func ViewInfo(viewInfo InputInfo) (totalView int, err error) {
  227. jsons, err := json.Marshal(viewInfo)
  228. if err != nil {
  229. log.Error("jsons failed", err)
  230. return 0, err
  231. }
  232. var jsonStr = []byte(jsons)
  233. var resultInfo ResultInfo
  234. loaded, totalView, err := GetResultFromElk(resultInfo, jsonStr)
  235. time := 0
  236. for {
  237. if loaded == 0 {
  238. loaded_next, totalView, err := GetResultFromElk(resultInfo, jsonStr)
  239. time++
  240. if loaded_next != 0 && time < 100 {
  241. return totalView, err
  242. }
  243. if time > 100 {
  244. break
  245. }
  246. } else {
  247. break
  248. }
  249. }
  250. return totalView, err
  251. }
  252. // @title AppointProjectView
  253. // @description 获取指定用户和项目的访问量
  254. // @param User string "用户名"
  255. // @param Project string "项目名"
  256. // @param Gte string "起始时间" 如time.Now().AddDate(0, 0, -1).Format(time.RFC3339)
  257. // @param Lte string "结束时间" 如time.Now().Format(time.RFC3339)
  258. // @return totalView int "访问量"
  259. func AppointProjectView(User string, Project string, Gte string, Lte string) (totalView int, err error) {
  260. ProjectViewInitInfo := ProjectViewInit(User, Project, Gte, Lte)
  261. ProjectTotalView, err := ViewInfo(ProjectViewInitInfo)
  262. return ProjectTotalView, err
  263. }
  264. //统计项目相关页面的访问量
  265. type ProjectInfo struct {
  266. /* 统计所有项目中该页面的浏览情况,不需要区分项目。以aiforge项目为例 */
  267. //地址:https://git.openi.org.cn/OpenI/aiforge/datasets?type=0
  268. Project_dataset_type_0 int
  269. //地址:https://git.openi.org.cn/OpenI/aiforge/datasets?type=1
  270. Project_dataset_type_1 int
  271. //地址:https://git.openi.org.cn/OpenI/aiforge/issues
  272. Project_issues int
  273. //地址:https://git.openi.org.cn/OpenI/aiforge/labels
  274. Project_labels int
  275. //地址:https://git.openi.org.cn/OpenI/aiforge/milestones
  276. Project_milestones int
  277. //地址:https://git.openi.org.cn/OpenI/aiforge/pulls
  278. Project_pulls int
  279. //地址:https://git.openi.org.cn/OpenI/aiforge/release
  280. Project_release int
  281. //地址:https://git.openi.org.cn/OpenI/aiforge/wiki
  282. Project_wiki int
  283. //地址:https://git.openi.org.cn/OpenI/aiforge/activity
  284. Project_activity int
  285. //地址:https://git.openi.org.cn/OpenI/aiforge/cloudbrain
  286. Project_cloudbrain int
  287. //地址:https://git.openi.org.cn/OpenI/aiforge/modelarts
  288. Project_modelarts int
  289. //地址:https://git.openi.org.cn/OpenI/aiforge/blockchain
  290. Project_blockchain int
  291. //地址:https://git.openi.org.cn/OpenI/aiforge/watchers
  292. Project_watchers int
  293. //地址:https://git.openi.org.cn/OpenI/aiforge/stars
  294. Project_stars int
  295. //地址:https://git.openi.org.cn/OpenI/aiforge/forks
  296. Project_forks int
  297. }
  298. type ErrorInfo struct {
  299. Project_dataset_type_0 error
  300. Project_dataset_type_1 error
  301. Project_issues error
  302. Project_labels error
  303. Project_milestones error
  304. Project_pulls error
  305. Project_release error
  306. Project_wiki error
  307. Project_activity error
  308. Project_cloudbrain error
  309. Project_modelarts error
  310. Project_blockchain error
  311. Project_watchers error
  312. Project_stars error
  313. Project_forks error
  314. }
  315. // @title AllProjectView
  316. // @description 获取指定用户和项目的访问量
  317. // @param Gte string "起始时间" 如time.Now().AddDate(0, 0, -1).Format(time.RFC3339)
  318. // @param Lte string "结束时间"
  319. // @return projectInfo ProjectInfo "统计所有项目中页面的浏览情况,不需要区分项目"
  320. func AllProjectView(Gte string, Lte string) (projectViewInfo ProjectInfo, errorInfo ErrorInfo) {
  321. projectViewInfo.Project_dataset_type_0, errorInfo.Project_dataset_type_0 = ViewInfo(AllProjectViewInit("/datasets?type=0", "%{[request][2]}", Gte, Lte))
  322. projectViewInfo.Project_dataset_type_1, errorInfo.Project_dataset_type_1 = ViewInfo(AllProjectViewInit("/datasets?type=1", "%{[request][2]}", Gte, Lte))
  323. projectViewInfo.Project_issues, errorInfo.Project_issues = ViewInfo(AllProjectViewInit("/issues HTTP/2.0", "%{[request][2]}", Gte, Lte))
  324. projectViewInfo.Project_labels, errorInfo.Project_labels = ViewInfo(TagNameInit("/labels HTTP/2.0", "labels", Gte, Lte))
  325. projectViewInfo.Project_milestones, errorInfo.Project_milestones = ViewInfo(AllProjectViewInit("/milestones HTTP/2.0", "%{[request][2]}", Gte, Lte))
  326. projectViewInfo.Project_pulls, errorInfo.Project_pulls = ViewInfo(AllProjectViewInit("/pulls HTTP/2.0", "%{[request][2]}", Gte, Lte))
  327. projectViewInfo.Project_release, errorInfo.Project_release = ViewInfo(AllProjectViewInit("/release HTTP/2.0", "%{[request][2]}", Gte, Lte))
  328. projectViewInfo.Project_wiki, errorInfo.Project_wiki = ViewInfo(AllProjectViewInit("/wiki HTTP/2.0", "%{[request][2]}", Gte, Lte))
  329. projectViewInfo.Project_activity, errorInfo.Project_activity = ViewInfo(AllProjectViewInit("/activity HTTP/2.0", "%{[request][2]}", Gte, Lte))
  330. projectViewInfo.Project_cloudbrain, errorInfo.Project_cloudbrain = ViewInfo(AllProjectViewInit("/cloudbrain HTTP/2.0", "%{[request][2]}", Gte, Lte))
  331. projectViewInfo.Project_modelarts, errorInfo.Project_modelarts = ViewInfo(AllProjectViewInit("/modelarts HTTP/2.0", "%{[request][2]}", Gte, Lte))
  332. projectViewInfo.Project_blockchain, errorInfo.Project_blockchain = ViewInfo(AllProjectViewInit("/blockchain HTTP/2.0", "%{[request][2]}", Gte, Lte))
  333. projectViewInfo.Project_watchers, errorInfo.Project_watchers = ViewInfo(AllProjectViewInit("/watchers HTTP/2.0", "%{[request][2]}", Gte, Lte))
  334. projectViewInfo.Project_stars, errorInfo.Project_stars = ViewInfo(AllProjectViewInit("/stars HTTP/2.0", "%{[request][2]}", Gte, Lte))
  335. projectViewInfo.Project_forks, errorInfo.Project_forks = ViewInfo(AllProjectViewInit("/forks HTTP/2.0", "%{[request][2]}", Gte, Lte))
  336. return projectViewInfo, errorInfo
  337. }