Source.regex seemingly not parsing log line properly

I hope someone can help me understand what I’m doing wrong here. I want to parse certain values from the log line below into labels, but no matter what I do, no new labels are created.

Log line:

2025-03-24T11:34:43.331Z [jfrt ] [WARN ] [                 [] [MirrorHeartbeatServiceImpl:405] [hbScheduler_Worker-2] - Found disabled member docker-local, no heartbeat will be sent.

Alloy config:

loki.source.kubernetes "artifactory_containers" {
  targets = discovery.relabel.artifactory_containers.output
  forward_to = [loki.process.artifactory_service.receiver]
}

loki.process "artifactory_service" {
  forward_to = [loki.relabel.REDACTED.receiver, loki.echo.debug.receiver]

  stage.decolorize {
  }
  stage.regex {
    expression = "^(?P<timestamp>[^ ]*) \\[(?P<service_type>[^\\]]*)\\] \\[(?P<log_level>[^\\]]*)\\] (?P<message>.*)$"
  }
  stage.template {
    source = "service_type"
    template = `{{ TrimSpace .Value }}`
  }
  stage.template {
    source = "log_level"
    template = `{{ TrimSpace .Value }}`
  }
  stage.labels {
    values = {
      service_type = "service_type",
      log_level = "log_level",
    }
  }
  stage.timestamp {
    source = "timestamp"
    format = "2006-01-02T15:59:49.999Z"
  }
}

loki.echo "debug" {
}

loki.echo output:

alloy ts=2025-03-24T13:35:51.631937386Z level=info component_path=/ component_id=loki.echo.debug receiver=loki.echo.debug entry="2025-03-24T11:37:03.336Z [jfrt ] [WARN ] [
  [] [MirrorHeartbeatServiceImpl:405] [hbScheduler_Worker-7] - Found disabled member docker-local, no heartbeat will be sent.\n" labels="{container_name=\"artifactory-ha\
", instance=\"artifactory-ha/artifactory-ha-artifactory-ha-primary-0:artifactory-ha\", job=\"loki.source.kubernetes.artifactory_containers\"}"

I have gone through the documentation on loki.process up and down, but for the life of me I can’t figure out what I’m doing wrong.

Maybe because you are using backticks when you should be using double quotes?

I tested your config, this worked for me:

  stage.regex {
    expression = `^(?P<timestamp>[^ ]*) \[(?P<service_type>[^\]]*)\] \[(?P<log_level>[^\]]*)\] (?P<message>.*)$`
  }
  stage.template {
    source = "service_type"
    template = "{{ TrimSpace .Value }}"
  }
  stage.template {
    source = "log_level"
    template = "{{ TrimSpace .Value }}"
  }
  stage.labels {
    values = {
      service_type = "service_type",
      log_level = "log_level",
    }
  }
  stage.timestamp {
    source = "timestamp"
    format = "2006-01-02T15:59:49.999Z"
  }

@tonyswumac, did you mean backticks instead of double quotes? Looks like that solves the annoying escape character issue.

What is curious is that I actually got it working by adding (?s). Somehow, forcing the expression to single line did the trick, but I’m confused as to why.

stage.regex {
    expression = "^(?s)(?P<timestamp>[^\\ ]*) \\[(?P<service_type>[^\\]]*)\\] \\[(?P<loglevel>[^\\]]*)\\] (?P<message>\\[.*\\]*)$"
  }