Sharing Pino JSON configuration

Since I haven’t found any other threads or issues providing this pattern, I want to share an Alloy loki.process config that I devised to capture and format logs from Pino, a widely used NodeJS logging library. Of particular interest will be the way in which the numeric level values are translated into human readable “structured metadata” values using a Sprig template.

loki.process "pino_json" {
  stage.json {
    expressions = {
      level = "",
      pid = "",
      err = "",
      hostname = "", 
      message = "msg",
    }
  }

  stage.timestamp {
    source = "time"
    format = "UnixMs"
  }

  // Translate Pino numeric log levels
  stage.template {
      source   = "level"
      template = "{{ get (dict "+
        "10 \"trace\" "+
        "20 \"debug\" "+
        "30 \"info\" "+
        "40 \"warn\" "+
        "50 \"error\" "+
        "60 \"fatal\") .level }}"
  }

  // Level and Unfrequently searched fields belong here
  stage.structured_metadata {
    values = {
      level = "",
      pid = "",
      hostname = "",
    }
  }

  // Build the labels set - must be low-cardinality!
  stage.labels {
    values = {
      err = "",
    }
  }
  
  // The log body will just be the message
  stage.output {
    source = "message"
  }

  forward_to = [loki.write.pino_logs.receiver]
}

Tested with Loki 3.4.2

2 Likes