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.

repo.go 8.2 kB

Better logging (#6038) (#6095) * Panic don't fatal on create new logger Fixes #5854 Signed-off-by: Andrew Thornton <art27@cantab.net> * partial broken * Update the logging infrastrcture Signed-off-by: Andrew Thornton <art27@cantab.net> * Reset the skip levels for Fatal and Error Signed-off-by: Andrew Thornton <art27@cantab.net> * broken ncsa * More log.Error fixes Signed-off-by: Andrew Thornton <art27@cantab.net> * Remove nal * set log-levels to lowercase * Make console_test test all levels * switch to lowercased levels * OK now working * Fix vetting issues * Fix lint * Fix tests * change default logging to match current gitea * Improve log testing Signed-off-by: Andrew Thornton <art27@cantab.net> * reset error skip levels to 0 * Update documentation and access logger configuration * Redirect the router log back to gitea if redirect macaron log but also allow setting the log level - i.e. TRACE * Fix broken level caching * Refactor the router log * Add Router logger * Add colorizing options * Adjust router colors * Only create logger if they will be used * update app.ini.sample * rename Attribute ColorAttribute * Change from white to green for function * Set fatal/error levels * Restore initial trace logger * Fix Trace arguments in modules/auth/auth.go * Properly handle XORMLogger * Improve admin/config page * fix fmt * Add auto-compression of old logs * Update error log levels * Remove the unnecessary skip argument from Error, Fatal and Critical * Add stacktrace support * Fix tests * Remove x/sync from vendors? * Add stderr option to console logger * Use filepath.ToSlash to protect against Windows in tests * Remove prefixed underscores from names in colors.go * Remove not implemented database logger This was removed from Gogs on 4 Mar 2016 but left in the configuration since then. * Ensure that log paths are relative to ROOT_PATH * use path.Join * rename jsonConfig to logConfig * Rename "config" to "jsonConfig" to make it clearer * Requested changes * Requested changes: XormLogger * Try to color the windows terminal If successful default to colorizing the console logs * fixup * Colorize initially too * update vendor * Colorize logs on default and remove if this is not a colorizing logger * Fix documentation * fix test * Use go-isatty to detect if on windows we are on msys or cygwin * Fix spelling mistake * Add missing vendors * More changes * Rationalise the ANSI writer protection * Adjust colors on advice from @0x5c * Make Flags a comma separated list * Move to use the windows constant for ENABLE_VIRTUAL_TERMINAL_PROCESSING * Ensure matching is done on the non-colored message - to simpify EXPRESSION
6 years ago
Better logging (#6038) (#6095) * Panic don't fatal on create new logger Fixes #5854 Signed-off-by: Andrew Thornton <art27@cantab.net> * partial broken * Update the logging infrastrcture Signed-off-by: Andrew Thornton <art27@cantab.net> * Reset the skip levels for Fatal and Error Signed-off-by: Andrew Thornton <art27@cantab.net> * broken ncsa * More log.Error fixes Signed-off-by: Andrew Thornton <art27@cantab.net> * Remove nal * set log-levels to lowercase * Make console_test test all levels * switch to lowercased levels * OK now working * Fix vetting issues * Fix lint * Fix tests * change default logging to match current gitea * Improve log testing Signed-off-by: Andrew Thornton <art27@cantab.net> * reset error skip levels to 0 * Update documentation and access logger configuration * Redirect the router log back to gitea if redirect macaron log but also allow setting the log level - i.e. TRACE * Fix broken level caching * Refactor the router log * Add Router logger * Add colorizing options * Adjust router colors * Only create logger if they will be used * update app.ini.sample * rename Attribute ColorAttribute * Change from white to green for function * Set fatal/error levels * Restore initial trace logger * Fix Trace arguments in modules/auth/auth.go * Properly handle XORMLogger * Improve admin/config page * fix fmt * Add auto-compression of old logs * Update error log levels * Remove the unnecessary skip argument from Error, Fatal and Critical * Add stacktrace support * Fix tests * Remove x/sync from vendors? * Add stderr option to console logger * Use filepath.ToSlash to protect against Windows in tests * Remove prefixed underscores from names in colors.go * Remove not implemented database logger This was removed from Gogs on 4 Mar 2016 but left in the configuration since then. * Ensure that log paths are relative to ROOT_PATH * use path.Join * rename jsonConfig to logConfig * Rename "config" to "jsonConfig" to make it clearer * Requested changes * Requested changes: XormLogger * Try to color the windows terminal If successful default to colorizing the console logs * fixup * Colorize initially too * update vendor * Colorize logs on default and remove if this is not a colorizing logger * Fix documentation * fix test * Use go-isatty to detect if on windows we are on msys or cygwin * Fix spelling mistake * Add missing vendors * More changes * Rationalise the ANSI writer protection * Adjust colors on advice from @0x5c * Make Flags a comma separated list * Move to use the windows constant for ENABLE_VIRTUAL_TERMINAL_PROCESSING * Ensure matching is done on the non-colored message - to simpify EXPRESSION
6 years ago
Better logging (#6038) (#6095) * Panic don't fatal on create new logger Fixes #5854 Signed-off-by: Andrew Thornton <art27@cantab.net> * partial broken * Update the logging infrastrcture Signed-off-by: Andrew Thornton <art27@cantab.net> * Reset the skip levels for Fatal and Error Signed-off-by: Andrew Thornton <art27@cantab.net> * broken ncsa * More log.Error fixes Signed-off-by: Andrew Thornton <art27@cantab.net> * Remove nal * set log-levels to lowercase * Make console_test test all levels * switch to lowercased levels * OK now working * Fix vetting issues * Fix lint * Fix tests * change default logging to match current gitea * Improve log testing Signed-off-by: Andrew Thornton <art27@cantab.net> * reset error skip levels to 0 * Update documentation and access logger configuration * Redirect the router log back to gitea if redirect macaron log but also allow setting the log level - i.e. TRACE * Fix broken level caching * Refactor the router log * Add Router logger * Add colorizing options * Adjust router colors * Only create logger if they will be used * update app.ini.sample * rename Attribute ColorAttribute * Change from white to green for function * Set fatal/error levels * Restore initial trace logger * Fix Trace arguments in modules/auth/auth.go * Properly handle XORMLogger * Improve admin/config page * fix fmt * Add auto-compression of old logs * Update error log levels * Remove the unnecessary skip argument from Error, Fatal and Critical * Add stacktrace support * Fix tests * Remove x/sync from vendors? * Add stderr option to console logger * Use filepath.ToSlash to protect against Windows in tests * Remove prefixed underscores from names in colors.go * Remove not implemented database logger This was removed from Gogs on 4 Mar 2016 but left in the configuration since then. * Ensure that log paths are relative to ROOT_PATH * use path.Join * rename jsonConfig to logConfig * Rename "config" to "jsonConfig" to make it clearer * Requested changes * Requested changes: XormLogger * Try to color the windows terminal If successful default to colorizing the console logs * fixup * Colorize initially too * update vendor * Colorize logs on default and remove if this is not a colorizing logger * Fix documentation * fix test * Use go-isatty to detect if on windows we are on msys or cygwin * Fix spelling mistake * Add missing vendors * More changes * Rationalise the ANSI writer protection * Adjust colors on advice from @0x5c * Make Flags a comma separated list * Move to use the windows constant for ENABLE_VIRTUAL_TERMINAL_PROCESSING * Ensure matching is done on the non-colored message - to simpify EXPRESSION
6 years ago
Better logging (#6038) (#6095) * Panic don't fatal on create new logger Fixes #5854 Signed-off-by: Andrew Thornton <art27@cantab.net> * partial broken * Update the logging infrastrcture Signed-off-by: Andrew Thornton <art27@cantab.net> * Reset the skip levels for Fatal and Error Signed-off-by: Andrew Thornton <art27@cantab.net> * broken ncsa * More log.Error fixes Signed-off-by: Andrew Thornton <art27@cantab.net> * Remove nal * set log-levels to lowercase * Make console_test test all levels * switch to lowercased levels * OK now working * Fix vetting issues * Fix lint * Fix tests * change default logging to match current gitea * Improve log testing Signed-off-by: Andrew Thornton <art27@cantab.net> * reset error skip levels to 0 * Update documentation and access logger configuration * Redirect the router log back to gitea if redirect macaron log but also allow setting the log level - i.e. TRACE * Fix broken level caching * Refactor the router log * Add Router logger * Add colorizing options * Adjust router colors * Only create logger if they will be used * update app.ini.sample * rename Attribute ColorAttribute * Change from white to green for function * Set fatal/error levels * Restore initial trace logger * Fix Trace arguments in modules/auth/auth.go * Properly handle XORMLogger * Improve admin/config page * fix fmt * Add auto-compression of old logs * Update error log levels * Remove the unnecessary skip argument from Error, Fatal and Critical * Add stacktrace support * Fix tests * Remove x/sync from vendors? * Add stderr option to console logger * Use filepath.ToSlash to protect against Windows in tests * Remove prefixed underscores from names in colors.go * Remove not implemented database logger This was removed from Gogs on 4 Mar 2016 but left in the configuration since then. * Ensure that log paths are relative to ROOT_PATH * use path.Join * rename jsonConfig to logConfig * Rename "config" to "jsonConfig" to make it clearer * Requested changes * Requested changes: XormLogger * Try to color the windows terminal If successful default to colorizing the console logs * fixup * Colorize initially too * update vendor * Colorize logs on default and remove if this is not a colorizing logger * Fix documentation * fix test * Use go-isatty to detect if on windows we are on msys or cygwin * Fix spelling mistake * Add missing vendors * More changes * Rationalise the ANSI writer protection * Adjust colors on advice from @0x5c * Make Flags a comma separated list * Move to use the windows constant for ENABLE_VIRTUAL_TERMINAL_PROCESSING * Ensure matching is done on the non-colored message - to simpify EXPRESSION
6 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. // Copyright 2017 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package code
  5. import (
  6. "context"
  7. "os"
  8. "strings"
  9. "sync"
  10. "code.gitea.io/gitea/models"
  11. "code.gitea.io/gitea/modules/graceful"
  12. "code.gitea.io/gitea/modules/log"
  13. "code.gitea.io/gitea/modules/setting"
  14. "github.com/blevesearch/bleve"
  15. "github.com/blevesearch/bleve/analysis/analyzer/custom"
  16. "github.com/blevesearch/bleve/analysis/token/lowercase"
  17. "github.com/blevesearch/bleve/analysis/tokenizer/unicode"
  18. "github.com/blevesearch/bleve/search/query"
  19. "github.com/ethantkoenig/rupture"
  20. )
  21. const (
  22. repoIndexerAnalyzer = "repoIndexerAnalyzer"
  23. repoIndexerDocType = "repoIndexerDocType"
  24. repoIndexerLatestVersion = 4
  25. )
  26. type bleveIndexerHolder struct {
  27. index bleve.Index
  28. mutex sync.RWMutex
  29. cond *sync.Cond
  30. }
  31. func newBleveIndexerHolder() *bleveIndexerHolder {
  32. b := &bleveIndexerHolder{}
  33. b.cond = sync.NewCond(b.mutex.RLocker())
  34. return b
  35. }
  36. func (r *bleveIndexerHolder) set(index bleve.Index) {
  37. r.mutex.Lock()
  38. defer r.mutex.Unlock()
  39. r.index = index
  40. r.cond.Broadcast()
  41. }
  42. func (r *bleveIndexerHolder) get() bleve.Index {
  43. r.mutex.RLock()
  44. defer r.mutex.RUnlock()
  45. if r.index == nil {
  46. r.cond.Wait()
  47. }
  48. return r.index
  49. }
  50. // repoIndexer (thread-safe) index for repository contents
  51. var indexerHolder = newBleveIndexerHolder()
  52. // RepoIndexerOp type of operation to perform on repo indexer
  53. type RepoIndexerOp int
  54. const (
  55. // RepoIndexerOpUpdate add/update a file's contents
  56. RepoIndexerOpUpdate = iota
  57. // RepoIndexerOpDelete delete a file
  58. RepoIndexerOpDelete
  59. )
  60. // RepoIndexerData data stored in the repo indexer
  61. type RepoIndexerData struct {
  62. RepoID int64
  63. Content string
  64. }
  65. // Type returns the document type, for bleve's mapping.Classifier interface.
  66. func (d *RepoIndexerData) Type() string {
  67. return repoIndexerDocType
  68. }
  69. // RepoIndexerUpdate an update to the repo indexer
  70. type RepoIndexerUpdate struct {
  71. Filepath string
  72. Op RepoIndexerOp
  73. Data *RepoIndexerData
  74. }
  75. // AddToFlushingBatch adds the update to the given flushing batch.
  76. func (update RepoIndexerUpdate) AddToFlushingBatch(batch rupture.FlushingBatch) error {
  77. id := filenameIndexerID(update.Data.RepoID, update.Filepath)
  78. switch update.Op {
  79. case RepoIndexerOpUpdate:
  80. return batch.Index(id, update.Data)
  81. case RepoIndexerOpDelete:
  82. return batch.Delete(id)
  83. default:
  84. log.Error("Unrecognized repo indexer op: %d", update.Op)
  85. }
  86. return nil
  87. }
  88. // initRepoIndexer initialize repo indexer
  89. func initRepoIndexer(populateIndexer func() error) {
  90. indexer, err := openIndexer(setting.Indexer.RepoPath, repoIndexerLatestVersion)
  91. if err != nil {
  92. log.Fatal("InitRepoIndexer %s: %v", setting.Indexer.RepoPath, err)
  93. }
  94. if indexer != nil {
  95. indexerHolder.set(indexer)
  96. closeAtTerminate()
  97. // Continue population from where left off
  98. if err = populateIndexer(); err != nil {
  99. log.Fatal("PopulateRepoIndex: %v", err)
  100. }
  101. return
  102. }
  103. if err = createRepoIndexer(setting.Indexer.RepoPath, repoIndexerLatestVersion); err != nil {
  104. log.Fatal("CreateRepoIndexer: %v", err)
  105. }
  106. closeAtTerminate()
  107. // if there is any existing repo indexer metadata in the DB, delete it
  108. // since we are starting afresh. Also, xorm requires deletes to have a
  109. // condition, and we want to delete everything, thus 1=1.
  110. if err := models.DeleteAllRecords("repo_indexer_status"); err != nil {
  111. log.Fatal("DeleteAllRepoIndexerStatus: %v", err)
  112. }
  113. if err = populateIndexer(); err != nil {
  114. log.Fatal("PopulateRepoIndex: %v", err)
  115. }
  116. }
  117. func closeAtTerminate() {
  118. graceful.GetManager().RunAtTerminate(context.Background(), func() {
  119. log.Debug("Closing repo indexer")
  120. indexer := indexerHolder.get()
  121. if indexer != nil {
  122. err := indexer.Close()
  123. if err != nil {
  124. log.Error("Error whilst closing the repository indexer: %v", err)
  125. }
  126. }
  127. log.Info("PID: %d Repository Indexer closed", os.Getpid())
  128. })
  129. }
  130. // createRepoIndexer create a repo indexer if one does not already exist
  131. func createRepoIndexer(path string, latestVersion int) error {
  132. docMapping := bleve.NewDocumentMapping()
  133. numericFieldMapping := bleve.NewNumericFieldMapping()
  134. numericFieldMapping.IncludeInAll = false
  135. docMapping.AddFieldMappingsAt("RepoID", numericFieldMapping)
  136. textFieldMapping := bleve.NewTextFieldMapping()
  137. textFieldMapping.IncludeInAll = false
  138. docMapping.AddFieldMappingsAt("Content", textFieldMapping)
  139. mapping := bleve.NewIndexMapping()
  140. if err := addUnicodeNormalizeTokenFilter(mapping); err != nil {
  141. return err
  142. } else if err := mapping.AddCustomAnalyzer(repoIndexerAnalyzer, map[string]interface{}{
  143. "type": custom.Name,
  144. "char_filters": []string{},
  145. "tokenizer": unicode.Name,
  146. "token_filters": []string{unicodeNormalizeName, lowercase.Name},
  147. }); err != nil {
  148. return err
  149. }
  150. mapping.DefaultAnalyzer = repoIndexerAnalyzer
  151. mapping.AddDocumentMapping(repoIndexerDocType, docMapping)
  152. mapping.AddDocumentMapping("_all", bleve.NewDocumentDisabledMapping())
  153. indexer, err := bleve.New(path, mapping)
  154. if err != nil {
  155. return err
  156. }
  157. indexerHolder.set(indexer)
  158. return rupture.WriteIndexMetadata(path, &rupture.IndexMetadata{
  159. Version: latestVersion,
  160. })
  161. }
  162. func filenameIndexerID(repoID int64, filename string) string {
  163. return indexerID(repoID) + "_" + filename
  164. }
  165. func filenameOfIndexerID(indexerID string) string {
  166. index := strings.IndexByte(indexerID, '_')
  167. if index == -1 {
  168. log.Error("Unexpected ID in repo indexer: %s", indexerID)
  169. }
  170. return indexerID[index+1:]
  171. }
  172. // RepoIndexerBatch batch to add updates to
  173. func RepoIndexerBatch() rupture.FlushingBatch {
  174. return rupture.NewFlushingBatch(indexerHolder.get(), maxBatchSize)
  175. }
  176. // deleteRepoFromIndexer delete all of a repo's files from indexer
  177. func deleteRepoFromIndexer(repoID int64) error {
  178. query := numericEqualityQuery(repoID, "RepoID")
  179. searchRequest := bleve.NewSearchRequestOptions(query, 2147483647, 0, false)
  180. result, err := indexerHolder.get().Search(searchRequest)
  181. if err != nil {
  182. return err
  183. }
  184. batch := RepoIndexerBatch()
  185. for _, hit := range result.Hits {
  186. if err = batch.Delete(hit.ID); err != nil {
  187. return err
  188. }
  189. }
  190. return batch.Flush()
  191. }
  192. // RepoSearchResult result of performing a search in a repo
  193. type RepoSearchResult struct {
  194. RepoID int64
  195. StartIndex int
  196. EndIndex int
  197. Filename string
  198. Content string
  199. }
  200. // SearchRepoByKeyword searches for files in the specified repo.
  201. // Returns the matching file-paths
  202. func SearchRepoByKeyword(repoIDs []int64, keyword string, page, pageSize int) (int64, []*RepoSearchResult, error) {
  203. phraseQuery := bleve.NewMatchPhraseQuery(keyword)
  204. phraseQuery.FieldVal = "Content"
  205. phraseQuery.Analyzer = repoIndexerAnalyzer
  206. var indexerQuery query.Query
  207. if len(repoIDs) > 0 {
  208. var repoQueries = make([]query.Query, 0, len(repoIDs))
  209. for _, repoID := range repoIDs {
  210. repoQueries = append(repoQueries, numericEqualityQuery(repoID, "RepoID"))
  211. }
  212. indexerQuery = bleve.NewConjunctionQuery(
  213. bleve.NewDisjunctionQuery(repoQueries...),
  214. phraseQuery,
  215. )
  216. } else {
  217. indexerQuery = phraseQuery
  218. }
  219. from := (page - 1) * pageSize
  220. searchRequest := bleve.NewSearchRequestOptions(indexerQuery, pageSize, from, false)
  221. searchRequest.Fields = []string{"Content", "RepoID"}
  222. searchRequest.IncludeLocations = true
  223. result, err := indexerHolder.get().Search(searchRequest)
  224. if err != nil {
  225. return 0, nil, err
  226. }
  227. searchResults := make([]*RepoSearchResult, len(result.Hits))
  228. for i, hit := range result.Hits {
  229. var startIndex, endIndex int = -1, -1
  230. for _, locations := range hit.Locations["Content"] {
  231. location := locations[0]
  232. locationStart := int(location.Start)
  233. locationEnd := int(location.End)
  234. if startIndex < 0 || locationStart < startIndex {
  235. startIndex = locationStart
  236. }
  237. if endIndex < 0 || locationEnd > endIndex {
  238. endIndex = locationEnd
  239. }
  240. }
  241. searchResults[i] = &RepoSearchResult{
  242. RepoID: int64(hit.Fields["RepoID"].(float64)),
  243. StartIndex: startIndex,
  244. EndIndex: endIndex,
  245. Filename: filenameOfIndexerID(hit.ID),
  246. Content: hit.Fields["Content"].(string),
  247. }
  248. }
  249. return int64(result.Total), searchResults, nil
  250. }