AthennaMind / opnsense-exporter

OPNsense Exporter for Prometheus
Apache License 2.0
71 stars 6 forks source link

[BUG] - Parse Error on `api/unbound/diagnostics/stats` #12

Open kquinsland opened 5 months ago

kquinsland commented 5 months ago

The exporter seems to be unhappy with something coming back from the API when inquiring about Unbound DNS.

ts=2024-03-30T04:11:09.033Z caller=collector.go:138 level=error msg="failed to update" component=collector collector_name=unbound_dns err="opnsense-client api call error: endpoint: api/unbound/diagnostics/stats; failed status code: 0; msg: error parsing  to int: strconv.Atoi: parsing \"\": invalid syntax" 

Versions

OPNsense 24.1.4-amd64
FreeBSD 13.2-RELEASE-p10
OpenSSL 3.0.13

Using exporter v0.0.3

kquinsland commented 5 months ago

I do use Unbound so I can try to provide data from the API if the source of the error isn't obvious.

I wanted to ask if there's any plans to disable certain api end points?

E.G.: some --metric.disable=unbound flag to prevent the exporter from scraping that particular sub-system in opnsense?

Motivation:

ihatemodels commented 5 months ago

There are already implemented switches to disable particular subsystems. You should just pass the flag or set the corresponding env to true. This is already mentioned in the README #Exporters

./opnsense-exporter --help

      --[no-]exporter.disable-arp-table
                                 Disable the scraping of the ARP table
                                 ($OPNSENSE_EXPORTER_DISABLE_ARP_TABLE)
      --[no-]exporter.disable-cron-table
                                 Disable the scraping of the cron table
                                 ($OPNSENSE_EXPORTER_DISABLE_CRON_TABLE)
      --[no-]exporter.disable-wireguard
                                 Disable the scraping of Wireguard service
                                 ($OPNSENSE_EXPORTER_DISABLE_WIREGUARD)

However the unbound disable is currently not implemented, but I will add flag for it shortly. It will be included in the next release which we can do after we merge your 2 PRs.

Thanks for the help.

ihatemodels commented 5 months ago

About the error, can you please provide the response from the API if possible clearing any sensitive data first. I suppose there is some "stringful" integer returned from the API.

ihatemodels commented 5 months ago

The unbound disable flag was introduced in #14

kquinsland commented 5 months ago

About the error, can you please provide the response from the API if possible clearing any sensitive data first. I suppose there is some "stringful" integer returned from the API.

From browser dev tools, calls to:

/api/unbound/diagnostics/stats

Result in:

{
    "status": "ok",
    "data": {
        "thread0": {
            "num": {
                "queries": "58485",
                "queries_ip_ratelimited": "0",
                "queries_cookie_valid": "0",
                "queries_cookie_client": "0",
                "queries_cookie_invalid": "0",
                "cachehits": "42119",
                "cachemiss": "16366",
                "prefetch": "0",
                "queries_timed_out": "0",
                "expired": "0",
                "recursivereplies": "16366",
                "dnscrypt": {
                    "crypted": "0",
                    "cert": "0",
                    "cleartext": "0",
                    "malformed": "0"
                }
            },
            "query": {
                "queue_time_us": {
                    "max": "0"
                }
            },
            "requestlist": {
                "avg": "0.102835",
                "max": "6",
                "overwritten": "0",
                "exceeded": "0",
                "current": {
                    "all": "0",
                    "user": "0"
                }
            },
            "recursion": {
                "time": {
                    "avg": "0.133630",
                    "median": "0.107612"
                }
            },
            "tcpusage": "0"
        },
        "thread1": {
            "num": {
                "queries": "58634",
                "queries_ip_ratelimited": "0",
                "queries_cookie_valid": "0",
                "queries_cookie_client": "0",
                "queries_cookie_invalid": "0",
                "cachehits": "42174",
                "cachemiss": "16460",
                "prefetch": "0",
                "queries_timed_out": "0",
                "expired": "0",
                "recursivereplies": "16460",
                "dnscrypt": {
                    "crypted": "0",
                    "cert": "0",
                    "cleartext": "0",
                    "malformed": "0"
                }
            },
            "query": {
                "queue_time_us": {
                    "max": "0"
                }
            },
            "requestlist": {
                "avg": "0.105529",
                "max": "5",
                "overwritten": "0",
                "exceeded": "0",
                "current": {
                    "all": "0",
                    "user": "0"
                }
            },
            "recursion": {
                "time": {
                    "avg": "0.135741",
                    "median": "0.108197"
                }
            },
            "tcpusage": "0"
        },
        "thread2": {
            "num": {
                "queries": "58163",
                "queries_ip_ratelimited": "0",
                "queries_cookie_valid": "0",
                "queries_cookie_client": "0",
                "queries_cookie_invalid": "0",
                "cachehits": "42024",
                "cachemiss": "16139",
                "prefetch": "0",
                "queries_timed_out": "0",
                "expired": "0",
                "recursivereplies": "16139",
                "dnscrypt": {
                    "crypted": "0",
                    "cert": "0",
                    "cleartext": "0",
                    "malformed": "0"
                }
            },
            "query": {
                "queue_time_us": {
                    "max": "0"
                }
            },
            "requestlist": {
                "avg": "0.102113",
                "max": "10",
                "overwritten": "0",
                "exceeded": "0",
                "current": {
                    "all": "0",
                    "user": "0"
                }
            },
            "recursion": {
                "time": {
                    "avg": "0.133746",
                    "median": "0.10868"
                }
            },
            "tcpusage": "0"
        },
        "thread3": {
            "num": {
                "queries": "58425",
                "queries_ip_ratelimited": "0",
                "queries_cookie_valid": "0",
                "queries_cookie_client": "0",
                "queries_cookie_invalid": "0",
                "cachehits": "42025",
                "cachemiss": "16400",
                "prefetch": "0",
                "queries_timed_out": "0",
                "expired": "0",
                "recursivereplies": "16400",
                "dnscrypt": {
                    "crypted": "0",
                    "cert": "0",
                    "cleartext": "0",
                    "malformed": "0"
                }
            },
            "query": {
                "queue_time_us": {
                    "max": "0"
                }
            },
            "requestlist": {
                "avg": "0.101707",
                "max": "8",
                "overwritten": "0",
                "exceeded": "0",
                "current": {
                    "all": "0",
                    "user": "0"
                }
            },
            "recursion": {
                "time": {
                    "avg": "0.134549",
                    "median": "0.10744"
                }
            },
            "tcpusage": "0"
        },
        "thread4": {
            "num": {
                "queries": "58744",
                "queries_ip_ratelimited": "0",
                "queries_cookie_valid": "0",
                "queries_cookie_client": "0",
                "queries_cookie_invalid": "0",
                "cachehits": "42389",
                "cachemiss": "16355",
                "prefetch": "0",
                "queries_timed_out": "0",
                "expired": "0",
                "recursivereplies": "16354",
                "dnscrypt": {
                    "crypted": "0",
                    "cert": "0",
                    "cleartext": "0",
                    "malformed": "0"
                }
            },
            "query": {
                "queue_time_us": {
                    "max": "0"
                }
            },
            "requestlist": {
                "avg": "0.103088",
                "max": "7",
                "overwritten": "0",
                "exceeded": "0",
                "current": {
                    "all": "1",
                    "user": "1"
                }
            },
            "recursion": {
                "time": {
                    "avg": "0.134525",
                    "median": "0.107918"
                }
            },
            "tcpusage": "0"
        },
        "thread5": {
            "num": {
                "queries": "58633",
                "queries_ip_ratelimited": "0",
                "queries_cookie_valid": "0",
                "queries_cookie_client": "0",
                "queries_cookie_invalid": "0",
                "cachehits": "42313",
                "cachemiss": "16320",
                "prefetch": "0",
                "queries_timed_out": "0",
                "expired": "0",
                "recursivereplies": "16320",
                "dnscrypt": {
                    "crypted": "0",
                    "cert": "0",
                    "cleartext": "0",
                    "malformed": "0"
                }
            },
            "query": {
                "queue_time_us": {
                    "max": "0"
                }
            },
            "requestlist": {
                "avg": "0.106311",
                "max": "7",
                "overwritten": "0",
                "exceeded": "0",
                "current": {
                    "all": "0",
                    "user": "0"
                }
            },
            "recursion": {
                "time": {
                    "avg": "0.136922",
                    "median": "0.108184"
                }
            },
            "tcpusage": "0"
        },
        "thread6": {
            "num": {
                "queries": "58334",
                "queries_ip_ratelimited": "0",
                "queries_cookie_valid": "0",
                "queries_cookie_client": "0",
                "queries_cookie_invalid": "0",
                "cachehits": "41927",
                "cachemiss": "16407",
                "prefetch": "0",
                "queries_timed_out": "0",
                "expired": "0",
                "recursivereplies": "16407",
                "dnscrypt": {
                    "crypted": "0",
                    "cert": "0",
                    "cleartext": "0",
                    "malformed": "0"
                }
            },
            "query": {
                "queue_time_us": {
                    "max": "0"
                }
            },
            "requestlist": {
                "avg": "0.101908",
                "max": "5",
                "overwritten": "0",
                "exceeded": "0",
                "current": {
                    "all": "0",
                    "user": "0"
                }
            },
            "recursion": {
                "time": {
                    "avg": "0.135397",
                    "median": "0.108311"
                }
            },
            "tcpusage": "0"
        },
        "thread7": {
            "num": {
                "queries": "64390",
                "queries_ip_ratelimited": "0",
                "queries_cookie_valid": "0",
                "queries_cookie_client": "0",
                "queries_cookie_invalid": "0",
                "cachehits": "43171",
                "cachemiss": "21219",
                "prefetch": "0",
                "queries_timed_out": "0",
                "expired": "0",
                "recursivereplies": "21219",
                "dnscrypt": {
                    "crypted": "0",
                    "cert": "0",
                    "cleartext": "0",
                    "malformed": "0"
                }
            },
            "query": {
                "queue_time_us": {
                    "max": "0"
                }
            },
            "requestlist": {
                "avg": "0.0843584",
                "max": "7",
                "overwritten": "0",
                "exceeded": "0",
                "current": {
                    "all": "0",
                    "user": "0"
                }
            },
            "recursion": {
                "time": {
                    "avg": "0.125493",
                    "median": "0.0987917"
                }
            },
            "tcpusage": "0"
        },
        "total": {
            "num": {
                "queries": "473808",
                "queries_ip_ratelimited": "0",
                "queries_cookie_valid": "0",
                "queries_cookie_client": "0",
                "queries_cookie_invalid": "0",
                "cachehits": "338142",
                "cachemiss": "135666",
                "prefetch": "0",
                "queries_timed_out": "0",
                "expired": "0",
                "recursivereplies": "135665",
                "dnscrypt": {
                    "crypted": "0",
                    "cert": "0",
                    "cleartext": "0",
                    "malformed": "0"
                }
            },
            "query": {
                "queue_time_us": {
                    "max": "0"
                }
            },
            "requestlist": {
                "avg": "0.100386",
                "max": "10",
                "overwritten": "0",
                "exceeded": "0",
                "current": {
                    "all": "1",
                    "user": "1"
                }
            },
            "recursion": {
                "time": {
                    "avg": "0.133456",
                    "median": "0.106892"
                }
            },
            "tcpusage": "0"
        },
        "time": {
            "now": "1711845897.176575",
            "up": "123456.933498",
            "elapsed": "123456.933498"
        }
    }
}
ihatemodels commented 5 months ago

Thanks. I will work on fixing unbound in the next release

github-actions[bot] commented 3 months ago

Stale issue message

github-actions[bot] commented 3 weeks ago

Stale issue message

andresanches commented 2 weeks ago

Bump. This error is still happening with opnsense-exporter v0.0.5 and OPNSense 24.7.2 (commit 8ffbc6387). I also included a sample of the api response.

/api/unbound/diagnostics/stats response ```json { "status": "ok", "data": { "thread0": { "num": { "queries": "562", "queries_ip_ratelimited": "0", "queries_cookie_valid": "0", "queries_cookie_client": "0", "queries_cookie_invalid": "0", "cachehits": "110", "cachemiss": "452", "prefetch": "0", "queries_timed_out": "0", "expired": "0", "recursivereplies": "452", "dnscrypt": { "crypted": "0", "cert": "0", "cleartext": "0", "malformed": "0" } }, "query": { "queue_time_us": { "max": "0" } }, "requestlist": { "avg": "0.389381", "max": "19", "overwritten": "0", "exceeded": "0", "current": { "all": "0", "user": "0" } }, "recursion": { "time": { "avg": "0.060561", "median": "0.0419289" } }, "tcpusage": "0" }, "thread1": { "num": { "queries": "870", "queries_ip_ratelimited": "0", "queries_cookie_valid": "0", "queries_cookie_client": "0", "queries_cookie_invalid": "0", "cachehits": "441", "cachemiss": "429", "prefetch": "0", "queries_timed_out": "0", "expired": "0", "recursivereplies": "427", "dnscrypt": { "crypted": "0", "cert": "0", "cleartext": "0", "malformed": "0" } }, "query": { "queue_time_us": { "max": "0" } }, "requestlist": { "avg": "0.356643", "max": "17", "overwritten": "0", "exceeded": "2", "current": { "all": "0", "user": "0" } }, "recursion": { "time": { "avg": "0.066897", "median": "0.0435346" } }, "tcpusage": "0" }, "thread2": { "num": { "queries": "723", "queries_ip_ratelimited": "0", "queries_cookie_valid": "0", "queries_cookie_client": "0", "queries_cookie_invalid": "0", "cachehits": "323", "cachemiss": "400", "prefetch": "0", "queries_timed_out": "0", "expired": "0", "recursivereplies": "400", "dnscrypt": { "crypted": "0", "cert": "0", "cleartext": "0", "malformed": "0" } }, "query": { "queue_time_us": { "max": "0" } }, "requestlist": { "avg": "0.28", "max": "15", "overwritten": "0", "exceeded": "0", "current": { "all": "0", "user": "0" } }, "recursion": { "time": { "avg": "0.067971", "median": "0.0434678" } }, "tcpusage": "0" }, "total": { "num": { "queries": "2155", "queries_ip_ratelimited": "0", "queries_cookie_valid": "0", "queries_cookie_client": "0", "queries_cookie_invalid": "0", "cachehits": "874", "cachemiss": "1281", "prefetch": "0", "queries_timed_out": "0", "expired": "0", "recursivereplies": "1279", "dnscrypt": { "crypted": "0", "cert": "0", "cleartext": "0", "malformed": "0" } }, "query": { "queue_time_us": { "max": "0" } }, "requestlist": { "avg": "0.344262", "max": "19", "overwritten": "0", "exceeded": "2", "current": { "all": "0", "user": "0" } }, "recursion": { "time": { "avg": "0.064993", "median": "0.0429771" } }, "tcpusage": "0" }, "time": { "now": "1724321248.745413", "up": "6739.805945", "elapsed": "6739.805945" } } } ```
Jannik-Hm commented 1 week ago

Looking at opnsense/unbound_dns.go, it looks like the fields mem, num, unwanted, msg, rrset, infra, key, dnscrypt_shared_secret and dnscrypt_nonce are missing from the data object in the sample response of @andresanches.

Either these are (now) optional unbound stats or they got removed altogether.

Hope I didn't misinterpret any of the code @ihatemodels