Skip to content

feat(otel): add actor lifecycle + scheduler duration metrics#514

Open
Krisztian F (krisztianfekete) wants to merge 2 commits into
agent-substrate:mainfrom
krisztianfekete:feat/add-lifecycle-and-scheudler-metrics
Open

feat(otel): add actor lifecycle + scheduler duration metrics#514
Krisztian F (krisztianfekete) wants to merge 2 commits into
agent-substrate:mainfrom
krisztianfekete:feat/add-lifecycle-and-scheudler-metrics

Conversation

@krisztianfekete

@krisztianfekete Krisztian F (krisztianfekete) commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

This PR is the second slice of the platform-metrics split (#433).

It adds two duration histograms emitted by ateapi:

  • ate.actor.lifecycle.operation.duration: create/resume/suspend/pause/delete, labeled by operation, template, pool, sandbox class, and (on resume) snapshot kind
  • ate.scheduler.assignment.duration: worker-assignment step, labeled by outcome (assigned / no_free_worker / error) and pool

Tested e2e on a local kind cluste where: both metrics reach the otel-system collector with the expected labels (resume shows snapshot_kind=golden, scheduler shows outcome=assigned, no error.type on success).

  • Tests pass
  • Appropriate changes to documentation are included in the PR

@krisztianfekete
Krisztian F (krisztianfekete) marked this pull request as ready for review July 24, 2026 11:06

func (s *Service) CreateActor(ctx context.Context, req *ateapipb.CreateActorRequest) (*ateapipb.Actor, error) {
if err := validateCreateActorRequest(req); err != nil {
func (s *Service) CreateActor(ctx context.Context, req *ateapipb.CreateActorRequest) (created *ateapipb.Actor, err error) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are we swapping everything to be named return args, that's not a very common pattern. If you're trying to capture err can you just do var err error. I don't feel super duper strongly about this, but I personally find it a bit harder to read.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's intentional, because with a var err error the defer would capture the pre-mapping error and also misqualify error.type. Would you say a comment would make this clearer?

Comment on lines +38 to +41
s.instruments.recordLifecycleOp(ctx, ateattr.OperationDelete, start, err,
ateattr.TemplateNameKey.String(tmpl.GetActorTemplateName()),
ateattr.TemplateNamespaceKey.String(tmpl.GetActorTemplateNamespace()),
)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think the behavior of this might be confusing. If this method returns before tmpl is assigned it may create a record with empty name, namespace. I think it's better to just use the incoming values even if they don't exist, what do you think?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair, although DeleteActorRequest is an ObjectRef so there's no template. I'll just drop template labels from delete entirely.

// A nil *Instruments is a valid no-op, so call sites need no guard. Worker-count
// is registered separately (RegisterWorkerCount): a callback-driven observable,
// not a synchronous instrument.
type Instruments struct {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any reason this is public, seems like we could construct it locally rather than exporting it

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's exported because main.go builds it and passes it to NewService like e.g. RegisterWorkerCount, so this seemed like the consistent way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants