sqlite.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. package sqlite
  2. import (
  3. "fmt"
  4. "strconv"
  5. "sync"
  6. "time"
  7. "github.com/crowdsecurity/crowdsec/pkg/types"
  8. log "github.com/sirupsen/logrus"
  9. "github.com/jinzhu/gorm"
  10. _ "github.com/jinzhu/gorm/dialects/sqlite"
  11. _ "github.com/mattn/go-sqlite3"
  12. "gopkg.in/tomb.v2"
  13. )
  14. type Context struct {
  15. Db *gorm.DB //Pointer to sqlite db
  16. tx *gorm.DB //Pointer to current transaction (flushed on a regular basis)
  17. lastCommit time.Time
  18. flush bool
  19. count int32
  20. lock sync.Mutex //booboo
  21. PusherTomb tomb.Tomb
  22. //to manage auto cleanup : max number of records *or* oldest
  23. maxEventRetention int
  24. maxDurationRetention time.Duration
  25. }
  26. func NewSQLite(cfg map[string]string) (*Context, error) {
  27. var err error
  28. c := &Context{}
  29. if v, ok := cfg["max_records"]; ok {
  30. c.maxEventRetention, err = strconv.Atoi(v)
  31. if err != nil {
  32. log.Errorf("Ignoring invalid max_records '%s' : %s", v, err)
  33. }
  34. }
  35. if v, ok := cfg["max_records_age"]; ok {
  36. c.maxDurationRetention, err = time.ParseDuration(v)
  37. if err != nil {
  38. log.Errorf("Ignoring invalid duration '%s' : %s", v, err)
  39. }
  40. }
  41. if _, ok := cfg["db_path"]; !ok {
  42. return nil, fmt.Errorf("please specify a 'db_path' to SQLite db in the configuration")
  43. }
  44. if cfg["db_path"] == "" {
  45. return nil, fmt.Errorf("please specify a 'db_path' to SQLite db in the configuration")
  46. }
  47. log.Warningf("Starting SQLite backend, path:%s", cfg["db_path"])
  48. c.Db, err = gorm.Open("sqlite3", cfg["db_path"]+"?_busy_timeout=1000")
  49. if err != nil {
  50. return nil, fmt.Errorf("failed to open %s : %s", cfg["db_path"], err)
  51. }
  52. if val, ok := cfg["debug"]; ok && val == "true" {
  53. log.Infof("Enabling debug for sqlite")
  54. c.Db.LogMode(true)
  55. }
  56. c.flush, _ = strconv.ParseBool(cfg["flush"])
  57. // Migrate the schema
  58. c.Db.AutoMigrate(&types.EventSequence{}, &types.SignalOccurence{}, &types.BanApplication{})
  59. c.Db.Model(&types.SignalOccurence{}).Related(&types.EventSequence{})
  60. c.Db.Model(&types.SignalOccurence{}).Related(&types.BanApplication{})
  61. c.tx = c.Db.Begin()
  62. c.lastCommit = time.Now()
  63. ret := c.tx.Commit()
  64. if ret.Error != nil {
  65. return nil, fmt.Errorf("failed to commit records : %v", ret.Error)
  66. }
  67. c.tx = c.Db.Begin()
  68. if c.tx == nil {
  69. return nil, fmt.Errorf("failed to begin sqlite transac : %s", err)
  70. }
  71. //random attempt
  72. //c.maxEventRetention = 100
  73. c.PusherTomb.Go(func() error {
  74. c.AutoCommit()
  75. return nil
  76. })
  77. return c, nil
  78. }