mirror of
https://github.com/crawlab-team/crawlab.git
synced 2026-01-21 17:21:09 +01:00
迁移日志到MongoDB
This commit is contained in:
@@ -34,31 +34,13 @@ func main() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
log.Info("initialized config successfully")
|
log.Info("initialized config successfully")
|
||||||
|
|
||||||
// 初始化日志设置
|
|
||||||
logLevel := viper.GetString("log.level")
|
|
||||||
if logLevel != "" {
|
|
||||||
log.SetLevelFromString(logLevel)
|
|
||||||
}
|
|
||||||
log.Info("initialized log config successfully")
|
|
||||||
if viper.GetString("log.isDeletePeriodically") == "Y" {
|
|
||||||
err := services.InitDeleteLogPeriodically()
|
|
||||||
if err != nil {
|
|
||||||
log.Error("init DeletePeriodically failed")
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
log.Info("initialized periodically cleaning log successfully")
|
|
||||||
} else {
|
|
||||||
log.Info("periodically cleaning log is switched off")
|
|
||||||
}
|
|
||||||
|
|
||||||
// 初始化Mongodb数据库
|
// 初始化Mongodb数据库
|
||||||
if err := database.InitMongo(); err != nil {
|
if err := database.InitMongo(); err != nil {
|
||||||
log.Error("init mongodb error:" + err.Error())
|
log.Error("init mongodb error:" + err.Error())
|
||||||
debug.PrintStack()
|
debug.PrintStack()
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
log.Info("initialized MongoDB successfully")
|
log.Info("initialized mongodb successfully")
|
||||||
|
|
||||||
// 初始化Redis数据库
|
// 初始化Redis数据库
|
||||||
if err := database.InitRedis(); err != nil {
|
if err := database.InitRedis(); err != nil {
|
||||||
@@ -66,7 +48,14 @@ func main() {
|
|||||||
debug.PrintStack()
|
debug.PrintStack()
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
log.Info("initialized Redis successfully")
|
log.Info("initialized redis successfully")
|
||||||
|
|
||||||
|
// 初始化日志设置
|
||||||
|
if err := services.InitLogService(); err != nil {
|
||||||
|
log.Error("init log error:" + err.Error())
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
log.Info("initialized log successfully")
|
||||||
|
|
||||||
if model.IsMaster() {
|
if model.IsMaster() {
|
||||||
// 初始化定时任务
|
// 初始化定时任务
|
||||||
|
|||||||
@@ -1,12 +1,23 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crawlab/database"
|
||||||
"crawlab/utils"
|
"crawlab/utils"
|
||||||
"github.com/apex/log"
|
"github.com/apex/log"
|
||||||
|
"github.com/globalsign/mgo/bson"
|
||||||
"os"
|
"os"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type LogItem struct {
|
||||||
|
Id bson.ObjectId `json:"_id" bson:"_id"`
|
||||||
|
Message string `json:"msg" bson:"msg"`
|
||||||
|
TaskId string `json:"task_id" bson:"task_id"`
|
||||||
|
IsError bool `json:"is_error" bson:"is_error"`
|
||||||
|
Ts time.Time `json:"ts" bson:"ts"`
|
||||||
|
}
|
||||||
|
|
||||||
// 获取本地日志
|
// 获取本地日志
|
||||||
func GetLocalLog(logPath string) (fileBytes []byte, err error) {
|
func GetLocalLog(logPath string) (fileBytes []byte, err error) {
|
||||||
|
|
||||||
@@ -42,3 +53,27 @@ func GetLocalLog(logPath string) (fileBytes []byte, err error) {
|
|||||||
logBuf = logBuf[:n]
|
logBuf = logBuf[:n]
|
||||||
return logBuf, nil
|
return logBuf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func AddLogItem(l LogItem) error {
|
||||||
|
s, c := database.GetCol("logs")
|
||||||
|
defer s.Close()
|
||||||
|
if err := c.Insert(l); err != nil {
|
||||||
|
log.Errorf("insert log error: " + err.Error())
|
||||||
|
debug.PrintStack()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetLogItemList(filter interface{}, skip int, limit int, sortStr string) ([]LogItem, error) {
|
||||||
|
s, c := database.GetCol("logs")
|
||||||
|
defer s.Close()
|
||||||
|
|
||||||
|
var logItems []LogItem
|
||||||
|
if err := c.Find(filter).Skip(skip).Limit(limit).Sort(sortStr).All(&logItems); err != nil {
|
||||||
|
debug.PrintStack()
|
||||||
|
return logItems, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return logItems, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -109,6 +109,19 @@ func (t *Task) GetResults(pageNum int, pageSize int) (results []interface{}, tot
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Task) GetLogItems() (logItems []LogItem, err error) {
|
||||||
|
query := bson.M{
|
||||||
|
"task_id": t.Id,
|
||||||
|
}
|
||||||
|
|
||||||
|
logItems, err = GetLogItemList(query, 0, constants.Infinite, "+_id")
|
||||||
|
if err != nil {
|
||||||
|
return logItems, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return logItems, nil
|
||||||
|
}
|
||||||
|
|
||||||
func GetTaskList(filter interface{}, skip int, limit int, sortKey string) ([]Task, error) {
|
func GetTaskList(filter interface{}, skip int, limit int, sortKey string) ([]Task, error) {
|
||||||
s, c := database.GetCol("tasks")
|
s, c := database.GetCol("tasks")
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|||||||
@@ -235,12 +235,12 @@ func DeleteTask(c *gin.Context) {
|
|||||||
|
|
||||||
func GetTaskLog(c *gin.Context) {
|
func GetTaskLog(c *gin.Context) {
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
logStr, err := services.GetTaskLog(id)
|
logItems, err := services.GetTaskLog(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
HandleError(http.StatusInternalServerError, c, err)
|
HandleError(http.StatusInternalServerError, c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
HandleSuccessData(c, logStr)
|
HandleSuccessData(c, logItems)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetTaskResults(c *gin.Context) {
|
func GetTaskResults(c *gin.Context) {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
"crawlab/utils"
|
"crawlab/utils"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/apex/log"
|
"github.com/apex/log"
|
||||||
|
"github.com/globalsign/mgo"
|
||||||
"github.com/globalsign/mgo/bson"
|
"github.com/globalsign/mgo/bson"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@@ -162,5 +163,42 @@ func InitDeleteLogPeriodically() error {
|
|||||||
|
|
||||||
c.Start()
|
c.Start()
|
||||||
return nil
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func InitLogIndexes() error {
|
||||||
|
s, c := database.GetCol("logs")
|
||||||
|
defer s.Close()
|
||||||
|
|
||||||
|
_ = c.EnsureIndexKey("task_id")
|
||||||
|
_ = c.EnsureIndex(mgo.Index{
|
||||||
|
Key: []string{"$text:msg"},
|
||||||
|
})
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func InitLogService() error {
|
||||||
|
logLevel := viper.GetString("log.level")
|
||||||
|
if logLevel != "" {
|
||||||
|
log.SetLevelFromString(logLevel)
|
||||||
|
}
|
||||||
|
log.Info("initialized log config successfully")
|
||||||
|
if viper.GetString("log.isDeletePeriodically") == "Y" {
|
||||||
|
if err := InitDeleteLogPeriodically(); err != nil {
|
||||||
|
log.Error("init DeletePeriodically failed")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Info("initialized periodically cleaning log successfully")
|
||||||
|
} else {
|
||||||
|
log.Info("periodically cleaning log is switched off")
|
||||||
|
}
|
||||||
|
|
||||||
|
if model.IsMaster() {
|
||||||
|
if err := InitLogIndexes(); err != nil {
|
||||||
|
log.Errorf(err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"crawlab/constants"
|
"crawlab/constants"
|
||||||
"crawlab/database"
|
"crawlab/database"
|
||||||
"crawlab/entity"
|
"crawlab/entity"
|
||||||
@@ -160,15 +161,70 @@ func SetEnv(cmd *exec.Cmd, envs []model.Env, task model.Task, spider model.Spide
|
|||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetLogConfig(cmd *exec.Cmd, path string) error {
|
func SetLogConfig(cmd *exec.Cmd, t model.Task) error {
|
||||||
fLog, err := os.Create(path)
|
//fLog, err := os.Create(path)
|
||||||
|
//if err != nil {
|
||||||
|
// log.Errorf("create task log file error: %s", path)
|
||||||
|
// debug.PrintStack()
|
||||||
|
// return err
|
||||||
|
//}
|
||||||
|
//cmd.Stdout = fLog
|
||||||
|
//cmd.Stderr = fLog
|
||||||
|
|
||||||
|
// get stdout reader
|
||||||
|
stdout, err := cmd.StdoutPipe()
|
||||||
|
readerStdout := bufio.NewReader(stdout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("create task log file error: %s", path)
|
log.Errorf("get stdout error: %s", err.Error())
|
||||||
debug.PrintStack()
|
debug.PrintStack()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cmd.Stdout = fLog
|
|
||||||
cmd.Stderr = fLog
|
// get stderr reader
|
||||||
|
stderr, err := cmd.StderrPipe()
|
||||||
|
readerStderr := bufio.NewReader(stderr)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("get stdout error: %s", err.Error())
|
||||||
|
debug.PrintStack()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// read stdout
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
line, err := readerStdout.ReadString('\n')
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
line = strings.Replace(line, "\n", "", -1)
|
||||||
|
_ = model.AddLogItem(model.LogItem{
|
||||||
|
Id: bson.NewObjectId(),
|
||||||
|
Message: line,
|
||||||
|
TaskId: t.Id,
|
||||||
|
IsError: false,
|
||||||
|
Ts: time.Now(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// read stderr
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
line, err := readerStderr.ReadString('\n')
|
||||||
|
line = strings.Replace(line, "\n", "", -1)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
_ = model.AddLogItem(model.LogItem{
|
||||||
|
Id: bson.NewObjectId(),
|
||||||
|
Message: line,
|
||||||
|
TaskId: t.Id,
|
||||||
|
IsError: true,
|
||||||
|
Ts: time.Now(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,7 +316,7 @@ func ExecuteShellCmd(cmdStr string, cwd string, t model.Task, s model.Spider) (e
|
|||||||
cmd.Dir = cwd
|
cmd.Dir = cwd
|
||||||
|
|
||||||
// 日志配置
|
// 日志配置
|
||||||
if err := SetLogConfig(cmd, t.LogPath); err != nil {
|
if err := SetLogConfig(cmd, t); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -566,54 +622,60 @@ func SpiderFileCheck(t model.Task, spider model.Spider) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetTaskLog(id string) (logStr string, err error) {
|
func GetTaskLog(id string) (logItems []model.LogItem, err error) {
|
||||||
task, err := model.GetTask(id)
|
task, err := model.GetTask(id)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if IsMasterNode(task.NodeId.Hex()) {
|
logItems, err = task.GetLogItems()
|
||||||
if !utils.Exists(task.LogPath) {
|
|
||||||
fileDir, err := MakeLogDir(task)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
fileP := GetLogFilePaths(fileDir, task)
|
|
||||||
|
|
||||||
// 获取日志文件路径
|
|
||||||
fLog, err := os.Create(fileP)
|
|
||||||
defer fLog.Close()
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("create task log file error: %s", fileP)
|
|
||||||
debug.PrintStack()
|
|
||||||
}
|
|
||||||
task.LogPath = fileP
|
|
||||||
if err := task.Save(); err != nil {
|
|
||||||
log.Errorf(err.Error())
|
|
||||||
debug.PrintStack()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
// 若为主节点,获取本机日志
|
|
||||||
logBytes, err := model.GetLocalLog(task.LogPath)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf(err.Error())
|
|
||||||
logStr = err.Error()
|
|
||||||
} else {
|
|
||||||
logStr = utils.BytesToString(logBytes)
|
|
||||||
}
|
|
||||||
return logStr, err
|
|
||||||
}
|
|
||||||
// 若不为主节点,获取远端日志
|
|
||||||
logStr, err = GetRemoteLog(task)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf(err.Error())
|
return logItems, err
|
||||||
|
|
||||||
}
|
}
|
||||||
return logStr, err
|
|
||||||
|
return logItems, nil
|
||||||
|
|
||||||
|
//if IsMasterNode(task.NodeId.Hex()) {
|
||||||
|
// if !utils.Exists(task.LogPath) {
|
||||||
|
// fileDir, err := MakeLogDir(task)
|
||||||
|
//
|
||||||
|
// if err != nil {
|
||||||
|
// log.Errorf(err.Error())
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fileP := GetLogFilePaths(fileDir, task)
|
||||||
|
//
|
||||||
|
// // 获取日志文件路径
|
||||||
|
// fLog, err := os.Create(fileP)
|
||||||
|
// defer fLog.Close()
|
||||||
|
// if err != nil {
|
||||||
|
// log.Errorf("create task log file error: %s", fileP)
|
||||||
|
// debug.PrintStack()
|
||||||
|
// }
|
||||||
|
// task.LogPath = fileP
|
||||||
|
// if err := task.Save(); err != nil {
|
||||||
|
// log.Errorf(err.Error())
|
||||||
|
// debug.PrintStack()
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// // 若为主节点,获取本机日志
|
||||||
|
// logBytes, err := model.GetLocalLog(task.LogPath)
|
||||||
|
// if err != nil {
|
||||||
|
// log.Errorf(err.Error())
|
||||||
|
// logStr = err.Error()
|
||||||
|
// } else {
|
||||||
|
// logStr = utils.BytesToString(logBytes)
|
||||||
|
// }
|
||||||
|
// return logStr, err
|
||||||
|
//}
|
||||||
|
//// 若不为主节点,获取远端日志
|
||||||
|
//logStr, err = GetRemoteLog(task)
|
||||||
|
//if err != nil {
|
||||||
|
// log.Errorf(err.Error())
|
||||||
|
//
|
||||||
|
//}
|
||||||
|
//return logStr, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func CancelTask(id string) (err error) {
|
func CancelTask(id string) (err error) {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
storageClassName: manual
|
storageClassName: manual
|
||||||
capacity:
|
capacity:
|
||||||
storage: 10Gi
|
storage: 3Gi
|
||||||
accessModes:
|
accessModes:
|
||||||
- ReadWriteOnce
|
- ReadWriteOnce
|
||||||
hostPath:
|
hostPath:
|
||||||
@@ -25,4 +25,4 @@ spec:
|
|||||||
- ReadWriteOnce
|
- ReadWriteOnce
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
storage: 10Gi
|
storage: 3Gi
|
||||||
@@ -20,6 +20,12 @@ export default {
|
|||||||
type: Number,
|
type: Number,
|
||||||
default: 1
|
default: 1
|
||||||
},
|
},
|
||||||
|
logItem: {
|
||||||
|
type: Object,
|
||||||
|
default () {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
},
|
||||||
data: {
|
data: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
|
|||||||
@@ -158,6 +158,7 @@ export default {
|
|||||||
// https://vuejs.org/v2/guide/render-function.html#createElement-Arguments
|
// https://vuejs.org/v2/guide/render-function.html#createElement-Arguments
|
||||||
props: {
|
props: {
|
||||||
index: logItem.index,
|
index: logItem.index,
|
||||||
|
logItem,
|
||||||
data: isAnsi ? convert.toHtml(logItem.data) : logItem.data,
|
data: isAnsi ? convert.toHtml(logItem.data) : logItem.data,
|
||||||
searchString: this.searchString,
|
searchString: this.searchString,
|
||||||
active: logItem.active,
|
active: logItem.active,
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ const state = {
|
|||||||
taskList: [],
|
taskList: [],
|
||||||
taskListTotalCount: 0,
|
taskListTotalCount: 0,
|
||||||
taskForm: {},
|
taskForm: {},
|
||||||
taskLog: '',
|
taskLog: [],
|
||||||
currentLogIndex: 0,
|
currentLogIndex: 0,
|
||||||
taskResultsData: [],
|
taskResultsData: [],
|
||||||
taskResultsColumns: [],
|
taskResultsColumns: [],
|
||||||
@@ -41,12 +41,13 @@ const getters = {
|
|||||||
return keys
|
return keys
|
||||||
},
|
},
|
||||||
logData (state) {
|
logData (state) {
|
||||||
const data = state.taskLog.split('\n')
|
const data = state.taskLog
|
||||||
.map((d, i) => {
|
.map((d, i) => {
|
||||||
return {
|
return {
|
||||||
index: i + 1,
|
index: i + 1,
|
||||||
data: d,
|
active: state.currentLogIndex === i + 1,
|
||||||
active: state.currentLogIndex === i + 1
|
data: d.msg,
|
||||||
|
...d
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if (state.taskForm && state.taskForm.status === 'running') {
|
if (state.taskForm && state.taskForm.status === 'running') {
|
||||||
@@ -151,7 +152,7 @@ const actions = {
|
|||||||
getTaskLog ({ state, commit }, id) {
|
getTaskLog ({ state, commit }, id) {
|
||||||
return request.get(`/tasks/${id}/log`)
|
return request.get(`/tasks/${id}/log`)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
commit('SET_TASK_LOG', response.data.data)
|
commit('SET_TASK_LOG', response.data.data || [])
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
getTaskResults ({ state, commit }, id) {
|
getTaskResults ({ state, commit }, id) {
|
||||||
|
|||||||
Reference in New Issue
Block a user