Skip to content

Commit

Permalink
feat: k6runner: add check metadata and type to remote runner requests (
Browse files Browse the repository at this point in the history
…#928)

* k6runner: add check metadata and type to remote runner requests

* prober/browser,multihttp,scripted: fill CheckInfo

* make probers receive a model.Check instead of prober.Check

This makes region information available to probes
  • Loading branch information
roobre authored Oct 22, 2024
1 parent 560fe5e commit ce37f32
Show file tree
Hide file tree
Showing 23 changed files with 478 additions and 327 deletions.
38 changes: 36 additions & 2 deletions internal/k6runner/k6runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"strings"

"github.com/go-logfmt/logfmt"
smmmodel "github.com/grafana/synthetic-monitoring-agent/internal/model"
"github.com/grafana/synthetic-monitoring-agent/internal/prober/logger"
"github.com/prometheus/client_golang/prometheus"
dto "github.com/prometheus/client_model/go"
Expand All @@ -20,11 +21,18 @@ import (

// Script is a k6 script that a runner is able to run, with some added instructions for that runner to act on.
type Script struct {
Script []byte `json:"script"`
// Script is the blob of bytes that is to be run.
Script []byte `json:"script"`
// Settings is a common representation of the fields common to all implementation-specific check settings that the
// runners are interested about.
Settings Settings `json:"settings"`
// TODO: Add Metadata and Features.
// CheckInfo holds information about the SM check that triggered this script.
CheckInfo CheckInfo `json:"check"`
// TODO: Add features.
}

// Settings is a common representation of the fields common to all implementation-specific check settings that the
// runners are interested about.
type Settings struct {
// Timeout for k6 run, in milliseconds. This value is a configuration value for remote runners, which will instruct
// them to return an error if the operation takes longer than this time to complete. Clients should expect that
Expand All @@ -33,6 +41,32 @@ type Settings struct {
Timeout int64 `json:"timeout"`
}

// CheckInfo holds information about the SM check that triggered this script.
type CheckInfo struct {
// Type is the string representation of the check type this script belongs to (browser, scripted, multihttp, etc.)
Type string `json:"type"`
// Metadata is a collection of key/value pairs containing information about this check, such as check and tenant ID.
// It is loosely typed on purpose: Metadata should only be used for informational properties that will make its way
// into telemetry, and not for making decision on it.
Metadata map[string]any `json:"metadata"`
}

// CheckInfoFromSM returns a CheckInfo from the information of the given SM check.
func CheckInfoFromSM(smc smmmodel.Check) CheckInfo {
ci := CheckInfo{
Metadata: map[string]any{},
}

ci.Type = smc.Type().String()
ci.Metadata["id"] = smc.Id
ci.Metadata["tenantID"] = smc.TenantId
ci.Metadata["regionID"] = smc.RegionId
ci.Metadata["created"] = smc.Created
ci.Metadata["modified"] = smc.Modified

return ci
}

// ErrNoTimeout is returned by [Runner] implementations if the supplied script has a timeout of zero.
var ErrNoTimeout = errors.New("check has no timeout")

Expand Down
30 changes: 30 additions & 0 deletions internal/k6runner/k6runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ import (
"strings"
"testing"

"github.com/grafana/synthetic-monitoring-agent/internal/model"
"github.com/grafana/synthetic-monitoring-agent/internal/prober/logger"
"github.com/grafana/synthetic-monitoring-agent/internal/testhelper"
sm "github.com/grafana/synthetic-monitoring-agent/pkg/pb/synthetic_monitoring"
"github.com/prometheus/client_golang/prometheus"
dto "github.com/prometheus/client_model/go"
"github.com/prometheus/common/expfmt"
Expand Down Expand Up @@ -93,6 +95,34 @@ func TestScriptRun(t *testing.T) {
require.True(t, success)
}

func TestCheckInfoFromSM(t *testing.T) {
t.Parallel()

check := model.Check{
RegionId: 4,
Check: sm.Check{
Id: 69,
TenantId: 1234,
Created: 1234.5,
Modified: 12345.6,
Settings: sm.CheckSettings{
Browser: &sm.BrowserSettings{}, // Make it non-nil so type is Browser.
},
},
}

ci := CheckInfoFromSM(check)

require.Equal(t, sm.CheckTypeBrowser.String(), ci.Type)
require.Equal(t, map[string]any{
"id": check.Id,
"tenantID": check.TenantId,
"regionID": check.RegionId,
"created": check.Created,
"modified": check.Modified,
}, ci.Metadata)
}

type testRunner struct {
metrics []byte
logs []byte
Expand Down
5 changes: 3 additions & 2 deletions internal/prober/browser/browser.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"

"github.com/grafana/synthetic-monitoring-agent/internal/k6runner"
"github.com/grafana/synthetic-monitoring-agent/internal/model"
"github.com/grafana/synthetic-monitoring-agent/internal/prober/logger"
sm "github.com/grafana/synthetic-monitoring-agent/pkg/pb/synthetic_monitoring"
"github.com/prometheus/client_golang/prometheus"
Expand All @@ -26,7 +27,7 @@ type Prober struct {
processor *k6runner.Processor
}

func NewProber(ctx context.Context, check sm.Check, logger zerolog.Logger, runner k6runner.Runner) (Prober, error) {
func NewProber(ctx context.Context, check model.Check, logger zerolog.Logger, runner k6runner.Runner) (Prober, error) {
var p Prober

if check.Settings.Browser == nil {
Expand All @@ -40,7 +41,7 @@ func NewProber(ctx context.Context, check sm.Check, logger zerolog.Logger, runne
Settings: k6runner.Settings{
Timeout: check.Timeout,
},
// TODO: Add metadata & features here.
CheckInfo: k6runner.CheckInfoFromSM(check),
},
}

Expand Down
39 changes: 22 additions & 17 deletions internal/prober/browser/browser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"time"

"github.com/grafana/synthetic-monitoring-agent/internal/k6runner"
"github.com/grafana/synthetic-monitoring-agent/internal/model"
"github.com/grafana/synthetic-monitoring-agent/internal/testhelper"
sm "github.com/grafana/synthetic-monitoring-agent/pkg/pb/synthetic_monitoring"
"github.com/rs/zerolog"
Expand All @@ -19,33 +20,37 @@ func TestNewProber(t *testing.T) {
logger := zerolog.New(zerolog.NewTestWriter(t))

testcases := map[string]struct {
check sm.Check
check model.Check
expectFailure bool
}{
"valid": {
expectFailure: false,
check: sm.Check{
Target: "http://www.example.org",
Job: "test",
Frequency: 10 * 1000,
Timeout: 10 * 1000,
Probes: []int64{1},
Settings: sm.CheckSettings{
Browser: &sm.BrowserSettings{
Script: []byte("// test"),
check: model.Check{
Check: sm.Check{
Target: "http://www.example.org",
Job: "test",
Frequency: 10 * 1000,
Timeout: 10 * 1000,
Probes: []int64{1},
Settings: sm.CheckSettings{
Browser: &sm.BrowserSettings{
Script: []byte("// test"),
},
},
},
},
},
"invalid": {
expectFailure: true,
check: sm.Check{
Target: "http://www.example.org",
Job: "test",
Frequency: 10 * 1000,
Timeout: 10 * 1000,
Probes: []int64{1},
Settings: sm.CheckSettings{},
check: model.Check{
Check: sm.Check{
Target: "http://www.example.org",
Job: "test",
Frequency: 10 * 1000,
Timeout: 10 * 1000,
Probes: []int64{1},
Settings: sm.CheckSettings{},
},
},
},
}
Expand Down
5 changes: 3 additions & 2 deletions internal/prober/dns/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"strings"
"time"

"github.com/grafana/synthetic-monitoring-agent/internal/model"
"github.com/grafana/synthetic-monitoring-agent/internal/prober/dns/internal/bbe/config"
bbeprober "github.com/grafana/synthetic-monitoring-agent/internal/prober/dns/internal/bbe/prober"
"github.com/grafana/synthetic-monitoring-agent/internal/prober/logger"
Expand All @@ -21,7 +22,7 @@ type Prober struct {
experimental bool
}

func NewProber(check sm.Check) (Prober, error) {
func NewProber(check model.Check) (Prober, error) {
if check.Settings.Dns == nil {
return Prober{}, errUnsupportedCheck
}
Expand All @@ -35,7 +36,7 @@ func NewProber(check sm.Check) (Prober, error) {
}, nil
}

func NewExperimentalProber(check sm.Check) (Prober, error) {
func NewExperimentalProber(check model.Check) (Prober, error) {
p, err := NewProber(check)
if err != nil {
return p, err
Expand Down
37 changes: 21 additions & 16 deletions internal/prober/dns/dns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"time"

"github.com/go-kit/log"
"github.com/grafana/synthetic-monitoring-agent/internal/model"
"github.com/grafana/synthetic-monitoring-agent/internal/prober/dns/internal/bbe/config"
sm "github.com/grafana/synthetic-monitoring-agent/pkg/pb/synthetic_monitoring"
"github.com/miekg/dns"
Expand All @@ -27,17 +28,17 @@ func TestName(t *testing.T) {

func TestNewProber(t *testing.T) {
testcases := map[string]struct {
input sm.Check
input model.Check
expected Prober
ExpectError bool
}{
"default": {
input: sm.Check{
input: model.Check{Check: sm.Check{
Target: "www.grafana.com",
Settings: sm.CheckSettings{
Dns: &sm.DnsSettings{},
},
},
}},
expected: Prober{
config: config.Module{
Prober: "dns",
Expand All @@ -55,10 +56,12 @@ func TestNewProber(t *testing.T) {
ExpectError: false,
},
"no-settings": {
input: sm.Check{
Target: "www.grafana.com",
Settings: sm.CheckSettings{
Dns: nil,
input: model.Check{
Check: sm.Check{
Target: "www.grafana.com",
Settings: sm.CheckSettings{
Dns: nil,
},
},
},
expected: Prober{},
Expand Down Expand Up @@ -221,15 +224,17 @@ func TestProberRetries(t *testing.T) {
}
}()

p, err := NewExperimentalProber(sm.Check{
Target: "www.grafana.com",
Timeout: 20000,
Settings: sm.CheckSettings{
Dns: &sm.DnsSettings{
Server: l.LocalAddr().String(),
RecordType: sm.DnsRecordType_A,
Protocol: sm.DnsProtocol_UDP,
IpVersion: sm.IpVersion_V4,
p, err := NewExperimentalProber(model.Check{
Check: sm.Check{
Target: "www.grafana.com",
Timeout: 20000,
Settings: sm.CheckSettings{
Dns: &sm.DnsSettings{
Server: l.LocalAddr().String(),
RecordType: sm.DnsRecordType_A,
Protocol: sm.DnsProtocol_UDP,
IpVersion: sm.IpVersion_V4,
},
},
},
})
Expand Down
3 changes: 2 additions & 1 deletion internal/prober/grpc/grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"time"

"github.com/grafana/synthetic-monitoring-agent/internal/model"
"github.com/grafana/synthetic-monitoring-agent/internal/prober/logger"
"github.com/grafana/synthetic-monitoring-agent/internal/tls"
sm "github.com/grafana/synthetic-monitoring-agent/pkg/pb/synthetic_monitoring"
Expand All @@ -20,7 +21,7 @@ type Prober struct {
config config.Module
}

func NewProber(ctx context.Context, check sm.Check, logger zerolog.Logger) (Prober, error) {
func NewProber(ctx context.Context, check model.Check, logger zerolog.Logger) (Prober, error) {
if check.Settings.Grpc == nil {
return Prober{}, errUnsupportedCheck
}
Expand Down
23 changes: 14 additions & 9 deletions internal/prober/grpc/grpc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"io"
"testing"

"github.com/grafana/synthetic-monitoring-agent/internal/model"
sm "github.com/grafana/synthetic-monitoring-agent/pkg/pb/synthetic_monitoring"
"github.com/prometheus/blackbox_exporter/config"
promcfg "github.com/prometheus/common/config"
Expand All @@ -19,15 +20,17 @@ func TestName(t *testing.T) {

func TestNewProber(t *testing.T) {
testcases := map[string]struct {
input sm.Check
input model.Check
expected Prober
ExpectError bool
}{
"default": {
input: sm.Check{
Target: "www.grafana.com",
Settings: sm.CheckSettings{
Grpc: &sm.GrpcSettings{},
input: model.Check{
Check: sm.Check{
Target: "www.grafana.com",
Settings: sm.CheckSettings{
Grpc: &sm.GrpcSettings{},
},
},
},
expected: Prober{
Expand All @@ -42,10 +45,12 @@ func TestNewProber(t *testing.T) {
},
},
"no-settings": {
input: sm.Check{
Target: "www.grafana.com",
Settings: sm.CheckSettings{
Grpc: nil,
input: model.Check{
Check: sm.Check{
Target: "www.grafana.com",
Settings: sm.CheckSettings{
Grpc: nil,
},
},
},
ExpectError: true,
Expand Down
5 changes: 3 additions & 2 deletions internal/prober/http/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"strings"
"time"

"github.com/grafana/synthetic-monitoring-agent/internal/model"
"github.com/grafana/synthetic-monitoring-agent/internal/prober/logger"
"github.com/grafana/synthetic-monitoring-agent/internal/tls"
"github.com/grafana/synthetic-monitoring-agent/internal/version"
Expand All @@ -29,13 +30,13 @@ type Prober struct {
cacheBustingQueryParamName string
}

func NewProber(ctx context.Context, check sm.Check, logger zerolog.Logger, reservedHeaders http.Header) (Prober, error) {
func NewProber(ctx context.Context, check model.Check, logger zerolog.Logger, reservedHeaders http.Header) (Prober, error) {
if check.Settings.Http == nil {
return Prober{}, errUnsupportedCheck
}

if len(reservedHeaders) > 0 {
augmentHttpHeaders(&check, reservedHeaders)
augmentHttpHeaders(&check.Check, reservedHeaders)
}

cfg, err := settingsToModule(ctx, check.Settings.Http, logger)
Expand Down
Loading

0 comments on commit ce37f32

Please sign in to comment.