Alloy can't start because stage.match

We run a local point-of-sale (POS) application on a Windows machine. The application writes trace logs that indicate when it is started and when it shuts down. Since we do not have built-in metrics for the application’s runtime status, we want to extract that information from the logs and visualize it in Grafana.

We’re specifically looking for the following log lines:

  • :white_check_mark: "Application started" → POS application has started
  • :cross_mark: "Closing application" → POS application is shutting down

Goal

Build a dashboard that shows whether the POS application is currently running or stopped, based entirely on the logs ingested through Grafana Alloy and Loki.

What I’ve Configured in Alloy so far
I’ve configured Alloy to match these log lines and extract the status using the following block inside my loki.process pipeline:

stage.match {
  selector = "{applbl=\"appname\"} |= \"Application started\" or |= \"Closing application\""
  stages = [
    stage.regex {
      expression = "(?P<status>Application started|Closing application)"
    },
    stage.labels {
      values = {
        appstatus = "status"
      }
    }
  ]
}

This should assign a label appstatus with values like "Application started" or "Closing application" to the respective log lines.

Despite this configuration, Alloy fails to start with syntax errors pointing to the stage.match block. I suspect it might be due to incorrect nesting or syntax within the stages array.

Is there something wrong with how the stage.match block is defined? How can I correctly extract and label the application state from these logs?