Compare commits

...

3 Commits

Author SHA1 Message Date
qyzh 14df1f03fc fix log output 2020-12-06 22:40:09 +08:00
qyzh 19545f4cee modify accesslog, record git push event 2020-12-06 21:12:59 +08:00
qyzh 9ee9bc6945 add download log api 2020-11-14 21:53:37 +08:00
7 changed files with 238 additions and 1 deletions

155
modules/userlog/userlog.go Normal file
View File

@ -0,0 +1,155 @@
package userlog
import (
// "fmt"
// "path"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/gitgraph"
"code.gitea.io/gitea/modules/git"
repo_module "code.gitea.io/gitea/modules/repository"
"fmt"
"time"
//"net/http"
)
// func init(){
// filename := path.Join(setting.LogRootPath, "userlog.log")
// log.NewLogger(1000, "userlog", "file", fmt.Sprintf(`{"filename":"%s"}`, filename))
// }
type GraphItem = gitgraph.GraphItem
type GraphItems = gitgraph.GraphItems
type LogTemplate struct {
login string
time string
method string
uri string
proto string
response_code string
agent string
request_body string
}
func GetGraphAndBranch(ctx *context.Context, repo *models.Repository) ([]GraphItem, []*git.Branch) {
if repo.IsEmpty { // 项目是否为空
//ctx.JSON(409, api.APIError{
// Message: "Git Repository is empty.",
// URL: setting.API.SwaggerURL,
//})
return []GraphItem{}, nil
}
gitRepo, err := git.OpenRepository(repo.RepoPath())
if err != nil {
//ctx.ServerError("OpenRepository", err)
return []GraphItem{}, nil
}
graph, err := gitgraph.GetCommitGraphNoPage(gitRepo)
if err != nil {
//ctx.ServerError("GetCommitGraph", err)
return []GraphItem{}, nil
}
branches, err := repo_module.GetBranches(repo)
if err != nil {
//ctx.Error(http.StatusInternalServerError, "GetBranches", err)
return []GraphItem{}, nil
}
return graph, branches
}
func CompareCommitAndBranch(ctx *context.Context, repo *models.Repository, oldGraph []GraphItem, oldBranches []*git.Branch) {
newGraph, newBranches := GetGraphAndBranch(ctx, repo)
oldGraphLen := len(oldGraph)
oldBranchLen := len(oldBranches)
newGraphLen := len(newGraph)
newBranchLen := len(newBranches)
identity := "-"
if val, ok := ctx.Data["SignedUserName"]; ok {
if stringVal, ok := val.(string); ok && stringVal != "" {
identity = stringVal
}
}
if newGraphLen > oldGraphLen {
str := StringfyGraph(CompareGraph(newGraph, oldGraph))
//logTemplate := LogTemplate{
// login: " "+identity,
// time: " "+time.Now().Format("2006-01-02 15:04:05 -0700"),
// method: " "+ctx.Req.Method,
// uri: " "+ctx.Req.URL.RequestURI(),
// proto: " "+ctx.Req.Proto,
// response_code: " -",
// agent: " "+ctx.Req.UserAgent(),
// request_body: " "+str,
//}
logTemplate := fmt.Sprintf(
"{login: %s, time: %s, method: %s, uri: %s, proto: %s, response_code: -, agent: %s, request_body: %s}",
identity, time.Now().Format("2006-01-02 15:04:05 -0700"), ctx.Req.Method,
ctx.Req.URL.RequestURI(), ctx.Req.Proto, ctx.Req.UserAgent(), str)
accessLogger := log.GetLogger("access")
accessLogger.SendLog(log.INFO, "", "", 0, logTemplate, "")
}
if newBranchLen != oldBranchLen{
var str string
if newBranchLen > oldBranchLen {
branch := FindBranch(newBranches, oldBranches)
str = fmt.Sprintf("{action: createBranch, branch_name: %v}", branch.Name)
}
if newBranchLen < oldBranchLen {
branch := FindBranch(oldBranches, newBranches)
str = fmt.Sprintf("{action: deleteBranch, branch_name: %v}", branch.Name)
}
logTemplate := fmt.Sprintf(
"{login: %s, time: %s, method: %s, uri: %s, proto: %s, response_code: -, agent: %s, request_body: %s}",
identity, time.Now().Format("2006-01-02 15:04:05 -0700"), ctx.Req.Method,
ctx.Req.URL.RequestURI(), ctx.Req.Proto, ctx.Req.UserAgent(), str)
accessLogger := log.GetLogger("access")
accessLogger.SendLog(log.INFO, "", "", 0, logTemplate, "")
}
return
}
func CompareGraph(newGraph []GraphItem, oldGraph []GraphItem)([]GraphItem) {
resultLen := len(newGraph) - len(oldGraph)
result := make([]GraphItem, resultLen)
ptr1 := 0
ptr2 := 0
count := 0
for ; count < resultLen; {
for ; (ptr1<len(newGraph))&&(ptr2 >= len(oldGraph) || newGraph[ptr1].Rev != oldGraph[ptr2].Rev); {
result[count] = newGraph[ptr1]
count += 1
ptr1 += 1
}
ptr1 += 1
ptr2 += 1
}
return result
}
func StringfyGraph(Graph []GraphItem)(string){
str := "{action: commit, payload: ["
for i := 0; i < len(Graph); i++{
//str += fmt.Sprintf("%+v, ", Graph[i])
str += fmt.Sprintf("{GraphAcii: %s, Relation: %s, Branch: %s, Rev: %s, Date: %s, Author: %s, AuthorEmail: %s, ShortRev: %s, Subject: %s, OnlyRelation: %v}",
Graph[i].GraphAcii, Graph[i].Relation, Graph[i].Branch, Graph[i].Rev, Graph[i].Date, Graph[i].Author,
Graph[i].AuthorEmail, Graph[i].ShortRev, Graph[i].Subject, Graph[i].OnlyRelation)
}
str += "]}"
return str
}
func FindBranch(longerBranches []*git.Branch, shorterBranches []*git.Branch) (*git.Branch) {
for i := 0; i < len(shorterBranches); i++{
if longerBranches[i].Name != shorterBranches[i].Name{
return longerBranches[i]
}
}
return longerBranches[len(shorterBranches)]
}

View File

@ -82,6 +82,7 @@ import (
"code.gitea.io/gitea/routers/api/v1/settings"
_ "code.gitea.io/gitea/routers/api/v1/swagger" // for swagger generation
"code.gitea.io/gitea/routers/api/v1/user"
"code.gitea.io/gitea/routers/api/v1/trace"
"gitea.com/macaron/binding"
"gitea.com/macaron/macaron"
@ -970,6 +971,12 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Group("/topics", func() {
m.Get("/search", repo.TopicSearch)
})
m.Group("/log", func() {
m.Get("/list", trace.GetLogList)
m.Get("/download/:filename", trace.DownloadLog)
// m.Combo("/download").Post(bind(trace.LogDownloadOptions{}), trace.DownloadLog)
})
}, securityHeaders(), context.APIContexter(), sudo())
}

View File

@ -0,0 +1,62 @@
package trace
import (
// "fmt"
"os"
// "path/filepath"
"io/ioutil"
// "net/http"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/context"
)
type LogDownloadOptions struct {
FileName string `json:"filename" binding:"Required"`
}
func GetLogList(ctx *context.APIContext) {
var logList []string
dir_list, err := ioutil.ReadDir(setting.LogRootPath)
if err != nil {
ctx.ServerError("logList", err)
return
}
for i:=0; i<len(dir_list); i++ {
// fmt.Println(i, "=", v.Name())
logList = append(logList, dir_list[i].Name())
}
ctx.JSON(200, &logList)
}
type NotFoundError struct {
Message string `json:"message"`
}
func DownloadLog(ctx *context.APIContext) {
file_path := ctx.Params(":filename")
// file_path := data.FileName
path := setting.LogRootPath+"/"+file_path
b, err := PathExists(path)
if !b || err != nil {
// ctx.Error(http.StatusNotFound, "NoSuchFile", fmt.Sprintf("no such file: %s", file_path))
ctx.JSON(200, &NotFoundError{Message: "no such file!"})
} else {
ctx.ServeFile(path, file_path)
}
}
func PathExists(path string) (bool, error) {
_, err := os.Stat(path)
if err == nil {
return true, nil
}
if os.IsNotExist(err) {
return false, nil
}
return false, err
}

View File

@ -10,6 +10,7 @@ import (
"compress/gzip"
gocontext "context"
"fmt"
//"io"
"io/ioutil"
"net/http"
"os"
@ -32,6 +33,7 @@ import (
"code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/timeutil"
repo_service "code.gitea.io/gitea/services/repository"
"code.gitea.io/gitea/modules/userlog"
)
// HTTP implmentation git smart HTTP protocol
@ -368,8 +370,9 @@ func HTTP(ctx *context.Context) {
ctx.NotFound("Smart Git HTTP", err)
return
}
graph, branches := userlog.GetGraphAndBranch(ctx, repo)
route.handler(serviceHandler{cfg, w, r, dir, file, cfg.Env})
userlog.CompareCommitAndBranch(ctx, repo, graph, branches)
return
}
}
@ -570,6 +573,14 @@ func serviceRPC(h serviceHandler, service string) {
cmd.Stdin = reqBody
cmd.Stderr = &stderr
//var gitcontent bytes.Buffer
//rsp := io.MultiWriter(h.w, &gitcontent)
//h.w = rsp
//buf := new(bytes.Buffer)
//buf.ReadFrom(reqBody)
//accessLogger := log.GetLogger("access")
//accessLogger.SendLog(log.INFO, "", "", 0, "-------------\n"+buf.String()+"\n-------------\n", "")
pid := process.GetManager().Add(fmt.Sprintf("%s %s %s [repo_path: %s]", git.GitExecutable, service, "--stateless-rpc", h.dir), cancel)
defer process.GetManager().Remove(pid)

@ -0,0 +1 @@
Subproject commit d4c86e31027a1e099df108bf1c5ec1754c4578ed

@ -0,0 +1 @@
Subproject commit 0db5d458480499a7dcd1aa1040f3e77936400c06