Save the runner and environment id for executions monitoring.
This commit is contained in:
@ -48,11 +48,12 @@ func NewAWSFunctionWorkload(
|
|||||||
workload := &AWSFunctionWorkload{
|
workload := &AWSFunctionWorkload{
|
||||||
id: newUUID.String(),
|
id: newUUID.String(),
|
||||||
fs: make(map[dto.FilePath][]byte),
|
fs: make(map[dto.FilePath][]byte),
|
||||||
executions: storage.NewMonitoredLocalStorage[*dto.ExecutionRequest](monitoring.MeasurementExecutionsAWS, nil),
|
|
||||||
runningExecutions: make(map[execution.ID]context.CancelFunc),
|
runningExecutions: make(map[execution.ID]context.CancelFunc),
|
||||||
onDestroy: onDestroy,
|
onDestroy: onDestroy,
|
||||||
environment: environment,
|
environment: environment,
|
||||||
}
|
}
|
||||||
|
workload.executions = storage.NewMonitoredLocalStorage[*dto.ExecutionRequest](
|
||||||
|
monitoring.MeasurementExecutionsAWS, monitorExecutionsRunnerID(environment.ID(), workload.id))
|
||||||
workload.InactivityTimer = NewInactivityTimer(workload, func(_ Runner) error {
|
workload.InactivityTimer = NewInactivityTimer(workload, func(_ Runner) error {
|
||||||
return workload.Destroy()
|
return workload.Destroy()
|
||||||
})
|
})
|
||||||
|
@ -18,16 +18,18 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestAWSExecutionRequestIsStored(t *testing.T) {
|
func TestAWSExecutionRequestIsStored(t *testing.T) {
|
||||||
r, err := NewAWSFunctionWorkload(nil, nil)
|
environment := &ExecutionEnvironmentMock{}
|
||||||
|
environment.On("ID").Return(dto.EnvironmentID(tests.DefaultEnvironmentIDAsInteger))
|
||||||
|
r, err := NewAWSFunctionWorkload(environment, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
executionRequest := &dto.ExecutionRequest{
|
executionRequest := &dto.ExecutionRequest{
|
||||||
Command: "command",
|
Command: "command",
|
||||||
TimeLimit: 10,
|
TimeLimit: 10,
|
||||||
Environment: nil,
|
Environment: nil,
|
||||||
}
|
}
|
||||||
r.StoreExecution(defaultExecutionID, executionRequest)
|
r.StoreExecution(tests.DefaultEnvironmentIDAsString, executionRequest)
|
||||||
assert.True(t, r.ExecutionExists(defaultExecutionID))
|
assert.True(t, r.ExecutionExists(tests.DefaultEnvironmentIDAsString))
|
||||||
storedExecutionRunner, ok := r.executions.Pop(defaultExecutionID)
|
storedExecutionRunner, ok := r.executions.Pop(tests.DefaultEnvironmentIDAsString)
|
||||||
assert.True(t, ok, "Getting an execution should not return ok false")
|
assert.True(t, ok, "Getting an execution should not return ok false")
|
||||||
assert.Equal(t, executionRequest, storedExecutionRunner)
|
assert.Equal(t, executionRequest, storedExecutionRunner)
|
||||||
}
|
}
|
||||||
@ -58,6 +60,7 @@ func (a *awsEndpointMock) handler(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
func TestAWSFunctionWorkload_ExecuteInteractively(t *testing.T) {
|
func TestAWSFunctionWorkload_ExecuteInteractively(t *testing.T) {
|
||||||
environment := &ExecutionEnvironmentMock{}
|
environment := &ExecutionEnvironmentMock{}
|
||||||
|
environment.On("ID").Return(dto.EnvironmentID(tests.DefaultEnvironmentIDAsInteger))
|
||||||
environment.On("Image").Return("testImage or AWS endpoint")
|
environment.On("Image").Return("testImage or AWS endpoint")
|
||||||
r, err := NewAWSFunctionWorkload(environment, nil)
|
r, err := NewAWSFunctionWorkload(environment, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@ -72,8 +75,8 @@ func TestAWSFunctionWorkload_ExecuteInteractively(t *testing.T) {
|
|||||||
awsMock.ctx, cancel = context.WithCancel(context.Background())
|
awsMock.ctx, cancel = context.WithCancel(context.Background())
|
||||||
cancel()
|
cancel()
|
||||||
|
|
||||||
r.StoreExecution(defaultExecutionID, &dto.ExecutionRequest{})
|
r.StoreExecution(tests.DefaultEnvironmentIDAsString, &dto.ExecutionRequest{})
|
||||||
exit, _, err := r.ExecuteInteractively(defaultExecutionID, nil, io.Discard, io.Discard)
|
exit, _, err := r.ExecuteInteractively(tests.DefaultEnvironmentIDAsString, nil, io.Discard, io.Discard)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
<-exit
|
<-exit
|
||||||
assert.True(t, awsMock.hasConnected)
|
assert.True(t, awsMock.hasConnected)
|
||||||
@ -84,9 +87,9 @@ func TestAWSFunctionWorkload_ExecuteInteractively(t *testing.T) {
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
command := "sl"
|
command := "sl"
|
||||||
request := &dto.ExecutionRequest{Command: command}
|
request := &dto.ExecutionRequest{Command: command}
|
||||||
r.StoreExecution(defaultExecutionID, request)
|
r.StoreExecution(tests.DefaultEnvironmentIDAsString, request)
|
||||||
|
|
||||||
_, cancel, err := r.ExecuteInteractively(defaultExecutionID, nil, io.Discard, io.Discard)
|
_, cancel, err := r.ExecuteInteractively(tests.DefaultEnvironmentIDAsString, nil, io.Discard, io.Discard)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
<-time.After(tests.ShortTimeout)
|
<-time.After(tests.ShortTimeout)
|
||||||
cancel()
|
cancel()
|
||||||
@ -100,6 +103,7 @@ func TestAWSFunctionWorkload_ExecuteInteractively(t *testing.T) {
|
|||||||
|
|
||||||
func TestAWSFunctionWorkload_UpdateFileSystem(t *testing.T) {
|
func TestAWSFunctionWorkload_UpdateFileSystem(t *testing.T) {
|
||||||
environment := &ExecutionEnvironmentMock{}
|
environment := &ExecutionEnvironmentMock{}
|
||||||
|
environment.On("ID").Return(dto.EnvironmentID(tests.DefaultEnvironmentIDAsInteger))
|
||||||
environment.On("Image").Return("testImage or AWS endpoint")
|
environment.On("Image").Return("testImage or AWS endpoint")
|
||||||
r, err := NewAWSFunctionWorkload(environment, nil)
|
r, err := NewAWSFunctionWorkload(environment, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@ -114,12 +118,12 @@ func TestAWSFunctionWorkload_UpdateFileSystem(t *testing.T) {
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
command := "sl"
|
command := "sl"
|
||||||
request := &dto.ExecutionRequest{Command: command}
|
request := &dto.ExecutionRequest{Command: command}
|
||||||
r.StoreExecution(defaultExecutionID, request)
|
r.StoreExecution(tests.DefaultEnvironmentIDAsString, request)
|
||||||
myFile := dto.File{Path: "myPath", Content: []byte("myContent")}
|
myFile := dto.File{Path: "myPath", Content: []byte("myContent")}
|
||||||
|
|
||||||
err = r.UpdateFileSystem(&dto.UpdateFileSystemRequest{Copy: []dto.File{myFile}})
|
err = r.UpdateFileSystem(&dto.UpdateFileSystemRequest{Copy: []dto.File{myFile}})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
_, execCancel, err := r.ExecuteInteractively(defaultExecutionID, nil, io.Discard, io.Discard)
|
_, execCancel, err := r.ExecuteInteractively(tests.DefaultEnvironmentIDAsString, nil, io.Discard, io.Discard)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
<-time.After(tests.ShortTimeout)
|
<-time.After(tests.ShortTimeout)
|
||||||
execCancel()
|
execCancel()
|
||||||
@ -131,8 +135,10 @@ func TestAWSFunctionWorkload_UpdateFileSystem(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestAWSFunctionWorkload_Destroy(t *testing.T) {
|
func TestAWSFunctionWorkload_Destroy(t *testing.T) {
|
||||||
|
environment := &ExecutionEnvironmentMock{}
|
||||||
|
environment.On("ID").Return(dto.EnvironmentID(tests.DefaultEnvironmentIDAsInteger))
|
||||||
hasDestroyBeenCalled := false
|
hasDestroyBeenCalled := false
|
||||||
r, err := NewAWSFunctionWorkload(nil, func(_ Runner) error {
|
r, err := NewAWSFunctionWorkload(environment, func(_ Runner) error {
|
||||||
hasDestroyBeenCalled = true
|
hasDestroyBeenCalled = true
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
@ -53,9 +53,10 @@ func NewNomadJob(id string, portMappings []nomadApi.PortMapping,
|
|||||||
id: id,
|
id: id,
|
||||||
portMappings: portMappings,
|
portMappings: portMappings,
|
||||||
api: apiClient,
|
api: apiClient,
|
||||||
executions: storage.NewMonitoredLocalStorage[*dto.ExecutionRequest](monitoring.MeasurementExecutionsNomad, nil),
|
|
||||||
onDestroy: onDestroy,
|
onDestroy: onDestroy,
|
||||||
}
|
}
|
||||||
|
job.executions = storage.NewMonitoredLocalStorage[*dto.ExecutionRequest](
|
||||||
|
monitoring.MeasurementExecutionsNomad, monitorExecutionsRunnerID(job.Environment(), id))
|
||||||
job.InactivityTimer = NewInactivityTimer(job, onDestroy)
|
job.InactivityTimer = NewInactivityTimer(job, onDestroy)
|
||||||
return job
|
return job
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,12 @@ package runner
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/influxdata/influxdb-client-go/v2/api/write"
|
||||||
"github.com/openHPI/poseidon/pkg/dto"
|
"github.com/openHPI/poseidon/pkg/dto"
|
||||||
|
"github.com/openHPI/poseidon/pkg/monitoring"
|
||||||
|
"github.com/openHPI/poseidon/pkg/storage"
|
||||||
"io"
|
"io"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ExitInfo struct {
|
type ExitInfo struct {
|
||||||
@ -59,3 +63,13 @@ func FromContext(ctx context.Context) (Runner, bool) {
|
|||||||
runner, ok := ctx.Value(runnerContextKey).(Runner)
|
runner, ok := ctx.Value(runnerContextKey).(Runner)
|
||||||
return runner, ok
|
return runner, ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// monitorExecutionsRunnerID passes the id of the runner executing the execution into the monitoring Point p.
|
||||||
|
func monitorExecutionsRunnerID(env dto.EnvironmentID, runnerID string) storage.WriteCallback[*dto.ExecutionRequest] {
|
||||||
|
return func(p *write.Point, e *dto.ExecutionRequest, isDeletion bool) {
|
||||||
|
if !isDeletion && e != nil {
|
||||||
|
p.AddTag(monitoring.InfluxKeyRunnerID, runnerID)
|
||||||
|
p.AddTag(monitoring.InfluxKeyEnvironmentID, strconv.Itoa(int(env)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -30,8 +30,9 @@ const (
|
|||||||
MeasurementUsedRunner = measurementPrefix + "used_runners"
|
MeasurementUsedRunner = measurementPrefix + "used_runners"
|
||||||
|
|
||||||
// The keys for the monitored tags and fields.
|
// The keys for the monitored tags and fields.
|
||||||
influxKeyRunnerID = "runner_id"
|
|
||||||
influxKeyEnvironmentID = "environment_id"
|
InfluxKeyRunnerID = "runner_id"
|
||||||
|
InfluxKeyEnvironmentID = "environment_id"
|
||||||
influxKeyEnvironmentPrewarmingPoolSize = "prewarming_pool_size"
|
influxKeyEnvironmentPrewarmingPoolSize = "prewarming_pool_size"
|
||||||
influxKeyRequestSize = "request_size"
|
influxKeyRequestSize = "request_size"
|
||||||
)
|
)
|
||||||
@ -90,12 +91,12 @@ func AddRunnerMonitoringData(request *http.Request, runnerID string, environment
|
|||||||
|
|
||||||
// addRunnerID adds the runner id to the influx data point for the current request.
|
// addRunnerID adds the runner id to the influx data point for the current request.
|
||||||
func addRunnerID(r *http.Request, id string) {
|
func addRunnerID(r *http.Request, id string) {
|
||||||
addInfluxDBTag(r, influxKeyRunnerID, id)
|
addInfluxDBTag(r, InfluxKeyRunnerID, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// addEnvironmentID adds the environment id to the influx data point for the current request.
|
// addEnvironmentID adds the environment id to the influx data point for the current request.
|
||||||
func addEnvironmentID(r *http.Request, id dto.EnvironmentID) {
|
func addEnvironmentID(r *http.Request, id dto.EnvironmentID) {
|
||||||
addInfluxDBTag(r, influxKeyEnvironmentID, strconv.Itoa(int(id)))
|
addInfluxDBTag(r, InfluxKeyEnvironmentID, strconv.Itoa(int(id)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddRequestSize adds the size of the request body to the influx data point for the current request.
|
// AddRequestSize adds the size of the request body to the influx data point for the current request.
|
||||||
@ -117,7 +118,7 @@ func AddRequestSize(r *http.Request) {
|
|||||||
func ChangedPrewarmingPoolSize(id dto.EnvironmentID, count uint) {
|
func ChangedPrewarmingPoolSize(id dto.EnvironmentID, count uint) {
|
||||||
p := influxdb2.NewPointWithMeasurement(measurementPoolSize)
|
p := influxdb2.NewPointWithMeasurement(measurementPoolSize)
|
||||||
|
|
||||||
p.AddTag(influxKeyEnvironmentID, strconv.Itoa(int(id)))
|
p.AddTag(InfluxKeyEnvironmentID, strconv.Itoa(int(id)))
|
||||||
p.AddField(influxKeyEnvironmentPrewarmingPoolSize, count)
|
p.AddField(influxKeyEnvironmentPrewarmingPoolSize, count)
|
||||||
|
|
||||||
WriteInfluxPoint(p)
|
WriteInfluxPoint(p)
|
||||||
|
Reference in New Issue
Block a user