-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdatastore.go
139 lines (111 loc) · 3.31 KB
/
datastore.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package main
import (
"crypto/md5"
"encoding/json"
"fmt"
"log"
"strings"
"time"
)
// timezone which is used in stored documents
var timezone string = ""
// represent single build info which stored in database
type datBuild struct {
BuildParameters map[string]interface{} `json:"buildParams"`
Users string `json:"users"`
Name string `json:"name"`
Building bool `json:"building"`
Duration int64 `json:"duration"`
EstimatedDuration int64 `json:"estimatedDuration"`
Number int64 `json:"number"`
Result string `json:"result"`
Timestamp string `json:"timestamp"`
URL string `json:"url"`
BuiltOn string `json:"builtOn"`
}
// create build UID which is used for document's _id in elasticsearch
func (b *datBuild) getID() string {
data := []byte(b.Timestamp + b.URL)
return fmt.Sprintf("%x", md5.Sum(data))
}
// extract job name from url
func getJobName(url string) string {
s := strings.Split(url, "/")
if len(s) < 3 {
return url
}
return s[len(s)-3]
}
// extract build variables from list of actions
func getParams(act []Action) map[string]interface{} {
bp := make(map[string]interface{})
for _, a := range act {
for _, p := range a.Parameters {
bp[p.Name] = p.Value
}
}
return bp
}
// set correct timezone for timestamps according to system time
func setDocsTimezone() {
name, offsetSec := time.Now().Zone() // int seconds
hours := offsetSec / 3600
mins := (offsetSec % 3600) / 60
timezone = fmt.Sprintf("+%02d%02d", hours, mins)
log.Printf("%s timezone offset compared to UTC: %s", name, timezone)
}
// convert jenkins millisec timestamp into
// string formatted for elasticsearch
func msToStr(ms int64) string {
t := time.Unix(0, ms*int64(time.Millisecond))
return t.Format("2006-01-02T15:04:05") + timezone
}
// extract list of user(s) from list of actions
func getUsers(act []Action) string {
users := []string{}
for _, a := range act {
for _, c := range a.Causes {
if len(c.UserID) > 0 {
users = append(users, c.UserID)
}
}
}
return strings.Join(users, ";")
}
// convert Build to datBuild which is ready to be stored in DB
func getdatBuild(b Build) datBuild {
d := datBuild{}
d.Building = b.Building
d.Duration = b.Duration
d.EstimatedDuration = b.EstimatedDuration
d.Number = b.Number
d.Result = b.Result
d.URL = b.URL
d.BuiltOn = b.BuiltOn
d.Timestamp = msToStr(b.Timestamp)
d.Users = getUsers(b.Actions)
d.BuildParameters = getParams(b.Actions)
d.Name = getJobName(b.URL)
return d
}
// server which continuously takes builds from channel
// and saves them to datastore
func saveBuilds(c *config, ch chan Build) {
b := datBuild{}
docURL := ""
db := c.Datastore
for {
b = getdatBuild(<-ch)
docURL = fmt.Sprintf("%s/%s/build/%s", db.Url, db.Index, b.getID())
// skip build if it doesn't finished yet or
// if it already exist in datastore
if b.Building || isBuildExist(docURL, db.User, db.Password, db.Verify) {
continue
}
docBytes, err := json.Marshal(b)
if err != nil {
log.Printf("Save builds: json: %v", err)
}
createDoc(docURL+"/_create", db.User, db.Password, string(docBytes), db.Verify)
}
}