Home > Software design >  Hash#dig not evaluating as expected
Hash#dig not evaluating as expected

Time:03-14

I have the following log message from a Kubernetes pod in JSON

{
    "kubernetes": {
        "annotations": {
            "kubectl.kubernetes.io/default-container": "testapp",
            "kubectl.kubernetes.io/default-logs-container": "testapp",
            "kubernetes.io/psp": "eks.privileged",
            "sidecar.istio.io/status": "{\"initContainers\":[\"istio-init\"],\"containers\":[\"istio-proxy\"],\"volumes\":[\"istio-envoy\",\"istio-data\",\"istio-podinfo\",\"istio-token\",\"istiod-ca-cert\"],\"imagePullSecrets\":null,\"revision\":\"default\"}"
        },
        "container_hash": "678267890xxx.dkr.ecr.us-east-2.amazonaws.com/testapp-ui@sha256:cfc2c911a3530f5ccd84db2c3a4d81fc4b218804af199c60fd42c17633",
        "container_image": "678267890xxx.dkr.ecr.us-east-2.amazonaws.com/testapp-ui:378",
        "container_name": "testapp",
        "docker_id": "9f6a89247b28392ac52daa9ba7a19416f04100f6a6ef3b5c90be4f7c",
        "host": "ip-10-64-97-41.us-west-2.compute.internal",
        "labels": {
            "app.kubernetes.io/app-name": "testapp",
            "region": "us-east-2",
            "pod-template-hash": "567bd7f6d4",
            "service": "testapp",
            "service.istio.io/canonical-name": "testapp-istio",
            "service.istio.io/canonical-revision": "latest"
        },
        "namespace_name": "testingQA",
        "pod_id": "a4560ae2-a845-4ff9-91c6-9114a5f362bc",
        "pod_name": "testapp-deployment-543bd7f6d4-mpdft"
    },
    "message": "127.0.0.6 - - [09/Mar/2022:19:24:32  0000] \"GET / HTTP/1.1\" 200 41559 \"-\" \"kube-probe/1.20 \" \"-\"\n",
    "source": "stdout",
    "time": "2021-11-04T19:24:32.460076299Z"
}

I am trying to add a new field app_name based on the below condition. I am using the record_modifier filter in fluentd to do this

<filter**>
    @type record_modifier
    remove_keys _dummy_
    <record>
        _dummy_ ${record.key?("app") ? record["app_name"] = record["app"] : record.key?("kubernetes") && record.dig(:kubernetes, :labels, :service_name).nil? ? record["app_name"] = record["kubernetes"]["labels"]["service_name"] : record.key?("kubernetes") && record.dig(:kubernetes, :labels, :"app.kubernetes.io/app-name").nil? ? record["app_name"] = record.dig(:kubernetes, :labels, :"app.kubernetes.io/app-name") : record["app_name"] = "empty"}
    </record>
</filter>

From the log message the field record["kubernetes"]["labels"]["app.kubernetes.io/app-name"] has value "testapp". However it returns null. Not sure why this happens. Also observed that only the first dig command evaluates correctly. Any insights will be appreciated.

CodePudding user response:

As @muistooshort pointed out, it was an issue with using keys as symbols as opposed to strings. The below works

<filter**>
    @type record_modifier
    remove_keys _dummy_
    <record>
        _dummy_ ${record.key?("app") ? record["app_name"] = record["app"] : record.key?("kubernetes") && record.dig("kubernetes", "labels", "service_name").nil? ? record["app_name"] = record["kubernetes"]["labels"]["service_name"] : record.key?("kubernetes") && record.dig("kubernetes", "labels", "app.kubernetes.io/app-name").nil? ? record["app_name"] = record.dig("kubernetes", "labels", "app.kubernetes.io/app-name") : record["app_name"] = "empty"}
    </record>
</filter>
  • Related