How to remove items from extracted json map in Grafana Alloy before forwarding to Loki

I’m using Grafana Alloy to send JSON logs from a Caddy webserver to Loki. I’m able to extract the timestamp with the config below. However, I would like to remove original timestamp ts from the JSON log before sending it to Loki. I couldn’t figure out what function/module was available to do this. Can the JSON log be modified before sending? Thanks.

local.file_match "caddy" {
        path_targets = [{
                __address__ = "localhost",
                __path__    = "/var/log/access.log",
                job         = "caddy",
        }]
}

loki.process "caddy" {
        forward_to = [loki.write.default.receiver]

        stage.json {
                expressions = {
                        level     = "level",
                        timestamp = "ts",
                        status = "status",
                }
        }

        stage.labels {
                values = {
                        level = null,
                        status = null,
                }
        }

        stage.timestamp {
                source = "timestamp"
                format = "Unix"
        }

}

loki.source.file "caddy" {
        targets               = local.file_match.caddy.targets
        forward_to            = [loki.process.caddy.receiver]
}

loki.write "default" {
        endpoint {
                url = "..."
        }
        external_labels = {}
}
1 Like

I would want to tell you that this can be done in a stage.json block; those contain a set of JMESPath expressions that create the new JSON which will be sent forward, but my research is showing that JMESPath itself doesn’t yet have a way to surgically remove a key from an object, and so since alloy relies on JMESPath, I think this isn’t doable at this time.

Thanks. Taking a look, could it perhaps be done with filter projection and !=? Just a bit unsure how to put this in the config.

1 Like

I don’t think that would work because filter projections are removing/filtering entire records, not individual keys. For example here:

It throws out the record where state=stopped, but state=running still occurs in the remaining records (discarding records, not keys).

If you could develop a filter expression using that kind of syntax, you’d end up throwing out everything with a date range in the filter, not removing the date (as was the original Q)

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.