Commit 3b008d06 by Marcus Efraimsson Committed by GitHub

testdata: logs scenario (#17182)

Adds logs scenario which is quite basic and not that smart 
to begin with. This will hopefully ease development of 
Explore and support for logs in Grafana.
parent c82df97b
......@@ -2,6 +2,7 @@ package testdata
import (
"encoding/json"
"fmt"
"math"
"math/rand"
"strconv"
......@@ -261,6 +262,84 @@ func init() {
return queryRes
},
})
registerScenario(&Scenario{
Id: "logs",
Name: "Logs",
Handler: func(query *tsdb.Query, context *tsdb.TsdbQuery) *tsdb.QueryResult {
from := context.TimeRange.GetFromAsMsEpoch()
to := context.TimeRange.GetToAsMsEpoch()
lines := query.Model.Get("lines").MustInt64(10)
includeLevelColumn := query.Model.Get("levelColumn").MustBool(false)
logLevelGenerator := newRandomStringProvider([]string{
"emerg",
"alert",
"crit",
"critical",
"warn",
"warning",
"err",
"eror",
"error",
"info",
"notice",
"dbug",
"debug",
"trace",
"",
})
containerIDGenerator := newRandomStringProvider([]string{
"f36a9eaa6d34310686f2b851655212023a216de955cbcc764210cefa71179b1a",
"5a354a630364f3742c602f315132e16def594fe68b1e4a195b2fce628e24c97a",
})
hostnameGenerator := newRandomStringProvider([]string{
"srv-001",
"srv-002",
})
table := tsdb.Table{
Columns: []tsdb.TableColumn{
{Text: "time"},
{Text: "message"},
{Text: "container_id"},
{Text: "hostname"},
},
Rows: []tsdb.RowValues{},
}
if includeLevelColumn {
table.Columns = append(table.Columns, tsdb.TableColumn{Text: "level"})
}
for i := int64(0); i < lines && to > from; i++ {
row := tsdb.RowValues{float64(to)}
logLevel := logLevelGenerator.Next()
timeFormatted := time.Unix(to/1000, 0).Format(time.RFC3339)
lvlString := ""
if !includeLevelColumn {
lvlString = fmt.Sprintf("lvl=%s ", logLevel)
}
row = append(row, fmt.Sprintf("t=%s %smsg=\"Request Completed\" logger=context userId=1 orgId=1 uname=admin method=GET path=/api/datasources/proxy/152/api/prom/label status=502 remote_addr=[::1] time_ms=1 size=0 referer=\"http://localhost:3000/explore?left=%%5B%%22now-6h%%22,%%22now%%22,%%22Prometheus%%202.x%%22,%%7B%%7D,%%7B%%22ui%%22:%%5Btrue,true,true,%%22none%%22%%5D%%7D%%5D\"", timeFormatted, lvlString))
row = append(row, containerIDGenerator.Next())
row = append(row, hostnameGenerator.Next())
if includeLevelColumn {
row = append(row, logLevel)
}
table.Rows = append(table.Rows, row)
to -= query.IntervalMs
}
queryRes := tsdb.NewQueryResult()
queryRes.Tables = append(queryRes.Tables, &table)
return queryRes
},
})
}
func getRandomWalk(query *tsdb.Query, tsdbQuery *tsdb.TsdbQuery) *tsdb.QueryResult {
......
package testdata
import (
"math/rand"
"time"
)
type randomStringProvider struct {
r *rand.Rand
data []string
}
func newRandomStringProvider(data []string) *randomStringProvider {
return &randomStringProvider{
r: rand.New(rand.NewSource(time.Now().UnixNano())),
data: data,
}
}
func (p *randomStringProvider) Next() string {
return p.data[p.r.Int31n(int32(len(p.data)))]
}
......@@ -32,10 +32,11 @@ export class TestDataDatasource extends DataSourceApi<TestDataQuery> {
scenarioId: item.scenarioId,
intervalMs: options.intervalMs,
maxDataPoints: options.maxDataPoints,
datasourceId: this.id,
stringInput: item.stringInput,
points: item.points,
alias: item.alias,
datasourceId: this.id,
...item,
};
});
......
......@@ -40,8 +40,8 @@
<div class="gf-form gf-form">
<label class="gf-form-label query-keyword width-7">Type</label>
<div class="gf-form-select-wrapper">
<select
ng-model="ctrl.target.stream.type"
<select
ng-model="ctrl.target.stream.type"
class="gf-form-input"
ng-options="type for type in ['signal','logs', 'fetch']"
ng-change="ctrl.streamChanged()" />
......@@ -50,45 +50,60 @@
</div>
<div class="gf-form">
<label class="gf-form-label query-keyword">Speed (ms)</label>
<input type="number"
class="gf-form-input width-5"
placeholder="value"
ng-model="ctrl.target.stream.speed"
<input type="number"
class="gf-form-input width-5"
placeholder="value"
ng-model="ctrl.target.stream.speed"
min="10"
step="10"
ng-change="ctrl.streamChanged()" />
</div>
<div class="gf-form" ng-if="ctrl.target.stream.type === 'signal'">
<label class="gf-form-label query-keyword">Spread</label>
<input type="number"
class="gf-form-input width-5"
placeholder="value"
ng-model="ctrl.target.stream.spread"
<input type="number"
class="gf-form-input width-5"
placeholder="value"
ng-model="ctrl.target.stream.spread"
min="0.5"
step="0.1"
ng-change="ctrl.streamChanged()" />
</div>
<div class="gf-form" ng-if="ctrl.target.stream.type === 'signal'">
<label class="gf-form-label query-keyword">Noise</label>
<input type="number"
class="gf-form-input width-5"
placeholder="value"
ng-model="ctrl.target.stream.noise"
<input type="number"
class="gf-form-input width-5"
placeholder="value"
ng-model="ctrl.target.stream.noise"
min="0"
step="0.1"
ng-change="ctrl.streamChanged()" />
</div>
<div class="gf-form gf-form--grow" ng-if="ctrl.target.stream.type === 'fetch'">
<label class="gf-form-label query-keyword">URL</label>
<input type="string"
class="gf-form-input gf-form-label--grow"
placeholder="Fetch URL"
ng-model="ctrl.target.stream.url"
ng-change="ctrl.streamChanged()"
<input type="string"
class="gf-form-input gf-form-label--grow"
placeholder="Fetch URL"
ng-model="ctrl.target.stream.url"
ng-change="ctrl.streamChanged()"
ng-model-onblur />
</div>
<div class="gf-form gf-form--grow" ng-if="ctrl.target.stream.type !== 'fetch'">
<div class="gf-form-label gf-form-label--grow"></div>
</div>
</div>
<div class="gf-form-inline" ng-if="ctrl.scenario.id === 'logs'">
<div class="gf-form">
<label class="gf-form-label query-keyword">Lines</label>
<input type="number"
class="gf-form-input width-5"
placeholder="10"
ng-model="ctrl.target.lines"
ng-change="ctrl.refresh()"
ng-model-onblur />
</div>
<div class="gf-form">
<gf-form-switch class="gf-form" label="Level" label-class="query-keyword width-5" checked="ctrl.target.levelColumn" switch-class="max-width-6" on-change="ctrl.refresh()"></gf-form-switch>
</div>
</div>
</query-editor-row>
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