Compare commits
3 Commits
Author | SHA1 | Date |
---|---|---|
|
14df1f03fc | |
|
19545f4cee | |
|
9ee9bc6945 |
|
@ -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)]
|
||||
}
|
|
@ -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())
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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
|
Binary file not shown.
Loading…
Reference in New Issue