Commit 297162b5 authored by ale's avatar ale

More tests; fix date parsing on /search handler

parent bb662ef1
Pipeline #436 failed with stages
in 29 seconds
......@@ -3023,7 +3023,6 @@ logviewer.util.htq = function(q) {
};
logviewer.util.rfc3339 = function(d) {
// OMFG
var year = '' + d.getUTCFullYear();
var month = '' + (1 + d.getUTCMonth());
if (month.length < 2) { month = '0' + month; }
......@@ -3036,11 +3035,10 @@ logviewer.util.rfc3339 = function(d) {
var second = '' + d.getUTCSeconds();
if (second.length < 2) { second = '0' + second; }
return (year + '-' + month + '-' + day + 'T' + hour + ':' + minute + ':' + second);
return (year + '-' + month + '-' + day + 'T' + hour + ':' + minute + ':' + second + 'Z');
};
logviewer.util.html5DateTime = function(d) {
// OMFG
var year = '' + d.getUTCFullYear();
var month = '' + (1 + d.getUTCMonth());
if (month.length < 2) { month = '0' + month; }
......@@ -3069,6 +3067,8 @@ logviewer.util.parseRFC3339 = function(s) {
return new Date(Date.parse(s));
};
logviewer.util.parseHTML5DateTime = logviewer.util.parseRFC3339;
// UI functions.
logviewer.ui = {};
......@@ -3090,8 +3090,8 @@ logviewer.ui.updateFormWithParams = function(params) {
logviewer.ui.paramsFromForm = function() {
var params = {
start_time: logviewer.util.parseRFC3339($('#inputStartTime').val()),
end_time: logviewer.util.parseRFC3339($('#inputEndTime').val()),
start_time: logviewer.util.parseHTML5DateTime($('#inputStartTime').val()),
end_time: logviewer.util.parseHTML5DateTime($('#inputEndTime').val()),
query_string: $('#inputQuery').val(),
limit: 100,
};
......@@ -3103,9 +3103,9 @@ logviewer.ui.paramsFromForm = function() {
logviewer.paramsToURL = function(params) {
var qs = '';
qs += 'q=' + encodeURIComponent(params.query_string);
qs += '&start_time=' + encodeURIComponent(
qs += '&start=' + encodeURIComponent(
logviewer.util.rfc3339(params.start_time));
qs += '&end_time=' + encodeURIComponent(
qs += '&end=' + encodeURIComponent(
logviewer.util.rfc3339(params.end_time));
qs += '&limit=' + params.limit;
return '/search?' + qs;
......@@ -3121,10 +3121,10 @@ logviewer.paramsFromHash = function(h) {
limit: 100
};
if (req.st) {
params.start_time = logviewer.util.parseRFC3339(req.st[0]);
params.start_time = logviewer.util.parseHTML5DateTime(req.st[0]);
}
if (req.et) {
params.end_time = logviewer.util.parseRFC3339(req.et[0]);
params.end_time = logviewer.util.parseHTML5DateTime(req.et[0]);
}
if (req.q) {
params.query_string = req.q[0];
......@@ -3139,9 +3139,9 @@ logviewer.paramsToHash = function(params) {
var s = '';
s += 'q=' + encodeURIComponent(params.query_string);
s += ';st=' + encodeURIComponent(
logviewer.util.rfc3339(params.start_time));
logviewer.util.html5DateTime(params.start_time));
s += ';et=' + encodeURIComponent(
logviewer.util.rfc3339(params.end_time));
logviewer.util.html5DateTime(params.end_time));
return s;
};
......@@ -3184,7 +3184,6 @@ logviewer.init = function() {
logviewer.logsView = $('#viewport');
$('.time-offset-menu-item').click(function(event) {
//event.preventDefault();
var timeOff = parseInt($(this).attr('time-offset'));
var params = logviewer.ui.paramsFromForm();
var now = new Date();
......@@ -3227,7 +3226,7 @@ func staticJsLogviewerJs() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "static/js/logviewer.js", size: 6130, mode: os.FileMode(436), modTime: time.Unix(1503760972, 0)}
info := bindataFileInfo{name: "static/js/logviewer.js", size: 6170, mode: os.FileMode(436), modTime: time.Unix(1503779723, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
......@@ -61,7 +61,7 @@ func (l logFileList) Less(i, j int) bool {
return l[i].LastTimestamp.Before(l[j].LastTimestamp)
}
var logPathRx = regexp.MustCompile(`/([^/]+)/([^/]*)(?:\.\d+)?(\.gz|\.lz4)?$`)
var logPathRx = regexp.MustCompile(`/([^/]+)/([^/]*)\.log(?:\.\d+)?(\.gz|\.lz4)?$`)
func walkLogFiles(rootDir string) []LogFile {
// Ignore errors while walking the filesystem.
......@@ -338,10 +338,12 @@ func (w *tailWriter) incr(i int) int {
}
func (w *tailWriter) WriteLine(line []byte) error {
if cap(w.buf[w.pos]) < len(line) {
w.buf[w.pos] = make([]byte, len(line))
n := len(line)
if cap(w.buf[w.pos]) < n {
w.buf[w.pos] = make([]byte, n)
}
copy(w.buf[w.pos], line)
w.buf[w.pos] = w.buf[w.pos][:len(line)]
w.pos = w.incr(w.pos)
if w.pos == w.head {
......@@ -355,6 +357,7 @@ func (w *tailWriter) Flush() {
if _, err := w.Write(w.buf[w.head]); err != nil {
return
}
if _, err := w.Write(newline); err != nil {
return
}
......
package main
import (
"bytes"
"testing"
"time"
)
func TestBuildLogFileMap(t *testing.T) {
m, hosts, programs := buildLogFileMap("testdata")
if len(hosts) != 2 {
t.Errorf("expected 2 hosts, got %+v", hosts)
}
if len(programs) != 2 {
t.Errorf("expected 2 programs, got %+v", programs)
}
if len(m) != 3 {
t.Errorf("expected 3 logs, got %+v", m)
}
}
func TestQuery_NoLimit(t *testing.T) {
m, _, _ := buildLogFileMap("testdata")
q := &Query{
MessageMatch: []byte("prometheus"),
StartTime: time.Date(2017, 8, 25, 0, 0, 0, 0, time.UTC),
EndTime: time.Date(2017, 8, 26, 0, 0, 0, 0, time.UTC),
}
var out bytes.Buffer
err := executeQuery(m, q, &out)
if err != nil {
t.Fatal("executeQuery:", err)
}
expected := `2017-08-25T08:39:40+00:00 host1 useradd[11630]: new user: name=prometheus, UID=108, GID=112, home=/var/lib/prometheus, shell=/bin/false
2017-08-25T08:39:40+00:00 host2 useradd[11781]: new user: name=prometheus, UID=108, GID=112, home=/var/lib/prometheus, shell=/bin/false
`
if out.String() != expected {
t.Errorf("bad query result:\n%s", out.String())
}
}
func TestQuery_Limit(t *testing.T) {
m, _, _ := buildLogFileMap("testdata")
q := &Query{
MessageMatch: []byte("prometheus"),
StartTime: time.Date(2017, 8, 25, 0, 0, 0, 0, time.UTC),
EndTime: time.Date(2017, 8, 26, 0, 0, 0, 0, time.UTC),
TailCount: 10,
}
var out bytes.Buffer
err := executeQuery(m, q, &out)
if err != nil {
t.Fatal("executeQuery:", err)
}
expected := `2017-08-25T08:39:40+00:00 host1 useradd[11630]: new user: name=prometheus, UID=108, GID=112, home=/var/lib/prometheus, shell=/bin/false
2017-08-25T08:39:40+00:00 host2 useradd[11781]: new user: name=prometheus, UID=108, GID=112, home=/var/lib/prometheus, shell=/bin/false
`
if out.String() != expected {
t.Errorf("bad query result:\n%s", out.String())
}
}
......@@ -104,19 +104,22 @@ func (s *logHTTPServer) handleQuery(w http.ResponseWriter, r *http.Request) {
return
}
q.StartTime = time.Now().Add(-1 * time.Hour)
q.EndTime = time.Now()
now := time.Now().UTC()
q.StartTime = now.Add(-1 * time.Hour)
q.EndTime = now
q.TailCount = 100
if n, err := strconv.ParseInt(r.FormValue("limit"), 10, 64); err == nil {
q.TailCount = int(n)
}
if t, err := time.Parse(r.FormValue("start"), time.RFC3339); err == nil {
if t, err := time.Parse(time.RFC3339, r.FormValue("start")); err == nil {
q.StartTime = t
}
if t, err := time.Parse(r.FormValue("end"), time.RFC3339); err == nil {
if t, err := time.Parse(time.RFC3339, r.FormValue("end")); err == nil {
q.EndTime = t
}
log.Printf("query: %+v", q)
w.Header().Set("Content-Type", "text/plain")
if err := s.Query(q, w); err != nil {
// Try to send a HTTP error, may not succeed if we
......
package main
import (
"io/ioutil"
"net/http"
"net/http/httptest"
"net/url"
"testing"
)
func TestService_Query(t *testing.T) {
lsrv := &logHTTPServer{newLogViewer("testdata")}
h := http.NewServeMux()
h.HandleFunc("/search", lsrv.handleQuery)
srv := httptest.NewServer(h)
defer srv.Close()
resp, err := http.PostForm(srv.URL+"/search", url.Values{
"q": []string{"prometheus"},
"start": []string{"2017-08-25T00:00:00Z"},
"end": []string{"2017-08-26T00:00:00Z"},
"limit": []string{"10"},
})
if err != nil {
t.Fatal("PostForm:", err)
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
t.Fatalf("got status code %s, expected 200", resp.StatusCode)
}
data, _ := ioutil.ReadAll(resp.Body)
expected := `2017-08-25T08:39:40+00:00 host1 useradd[11630]: new user: name=prometheus, UID=108, GID=112, home=/var/lib/prometheus, shell=/bin/false
2017-08-25T08:39:40+00:00 host2 useradd[11781]: new user: name=prometheus, UID=108, GID=112, home=/var/lib/prometheus, shell=/bin/false
`
if string(data) != expected {
t.Fatalf("bad query result:\n%s", string(data))
}
}
......@@ -36,7 +36,7 @@ logviewer.util.rfc3339 = function(d) {
var second = '' + d.getUTCSeconds();
if (second.length < 2) { second = '0' + second; }
return (year + '-' + month + '-' + day + 'T' + hour + ':' + minute + ':' + second);
return (year + '-' + month + '-' + day + 'T' + hour + ':' + minute + ':' + second + 'Z');
};
logviewer.util.html5DateTime = function(d) {
......@@ -68,6 +68,8 @@ logviewer.util.parseRFC3339 = function(s) {
return new Date(Date.parse(s));
};
logviewer.util.parseHTML5DateTime = logviewer.util.parseRFC3339;
// UI functions.
logviewer.ui = {};
......@@ -89,8 +91,8 @@ logviewer.ui.updateFormWithParams = function(params) {
logviewer.ui.paramsFromForm = function() {
var params = {
start_time: logviewer.util.parseRFC3339($('#inputStartTime').val()),
end_time: logviewer.util.parseRFC3339($('#inputEndTime').val()),
start_time: logviewer.util.parseHTML5DateTime($('#inputStartTime').val()),
end_time: logviewer.util.parseHTML5DateTime($('#inputEndTime').val()),
query_string: $('#inputQuery').val(),
limit: 100,
};
......@@ -102,9 +104,9 @@ logviewer.ui.paramsFromForm = function() {
logviewer.paramsToURL = function(params) {
var qs = '';
qs += 'q=' + encodeURIComponent(params.query_string);
qs += '&start_time=' + encodeURIComponent(
qs += '&start=' + encodeURIComponent(
logviewer.util.rfc3339(params.start_time));
qs += '&end_time=' + encodeURIComponent(
qs += '&end=' + encodeURIComponent(
logviewer.util.rfc3339(params.end_time));
qs += '&limit=' + params.limit;
return '/search?' + qs;
......@@ -120,10 +122,10 @@ logviewer.paramsFromHash = function(h) {
limit: 100
};
if (req.st) {
params.start_time = logviewer.util.parseRFC3339(req.st[0]);
params.start_time = logviewer.util.parseHTML5DateTime(req.st[0]);
}
if (req.et) {
params.end_time = logviewer.util.parseRFC3339(req.et[0]);
params.end_time = logviewer.util.parseHTML5DateTime(req.et[0]);
}
if (req.q) {
params.query_string = req.q[0];
......@@ -138,9 +140,9 @@ logviewer.paramsToHash = function(params) {
var s = '';
s += 'q=' + encodeURIComponent(params.query_string);
s += ';st=' + encodeURIComponent(
logviewer.util.rfc3339(params.start_time));
logviewer.util.html5DateTime(params.start_time));
s += ';et=' + encodeURIComponent(
logviewer.util.rfc3339(params.end_time));
logviewer.util.html5DateTime(params.end_time));
return s;
};
......
2017-08-25T08:39:04+00:00 host1 useradd[9200]: new user: name=ntp, UID=107, GID=111, home=/home/ntp, shell=/bin/false
2017-08-25T08:39:40+00:00 host1 useradd[11630]: new user: name=prometheus, UID=108, GID=112, home=/var/lib/prometheus, shell=/bin/false
2017-08-25T08:39:52+00:00 host1 useradd[12591]: new group: name=etcd, GID=999
2017-08-25T08:39:52+00:00 host1 useradd[12591]: new user: name=etcd, UID=999, GID=999, home=/var/lib/etcd, shell=
2017-08-25T08:35:24+00:00 host2 cron[325]: (CRON) INFO (pidfile fd = 3)
2017-08-25T08:35:24+00:00 host2 cron[325]: (CRON) INFO (Running @reboot jobs)
2017-08-25T08:39:05+00:00 host2 useradd[9200]: new user: name=ntp, UID=107, GID=111, home=/home/ntp, shell=/bin/false
2017-08-25T08:39:40+00:00 host2 useradd[11781]: new user: name=prometheus, UID=108, GID=112, home=/var/lib/prometheus, shell=/bin/false
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment